首页 文章

Angular2绑定来自ngFor的ngModel

提问于
浏览
3

所以我使用 ngFor 动态渲染我的 textarea 但是我不知道如何在我的函数中传递 ngModel 来绑定它 .

<div *ngFor="let inputSearch of searchBoxCount; let i = index" [ngClass]="{'col-sm-3': swaggerParamLength=='3', 'col-sm-9': swaggerParamLength=='1'}">
   <textarea name="{{inputSearch.name}}" id="{{inputSearch.name}}" rows="3" class="search-area-txt" attr.placeholder="Search Product {{inputSearch.name}}"
     [(ngModel)]="inputSearch.name"></textarea>
  </div>

textarea例子:
enter image description here

textarea是根据我从api调用得到的响应的长度来呈现 searchBoxCount 基本上是 searchBoxCount.length ,所以如果它 length = 1那么它只会渲染1 textarea 如果它的3然后它将显示3 textareas . objs有不同的名称(例如:id / email / whatever),因此ngModel基于json对象的obj名称 .

如何将 inputSearch.name 绑定到我的函数 getQueryString()

getQueryString() {
    this.isLoading = true;
    let idInputValue = inputSearch.name; //bind it here

    return "?id=" + idInputValue
        .split("\n") // Search values are separated by newline and put it in array collection.
        .filter(function(str) {
            return str !== ""
        })
        .join("&id=");
}

搜索func调用getQueryString()的位置

searchProduct() {
    let queryString1 = this.getQueryString();
    this._searchService.getProduct(queryString1)
        .subscribe(data => {
            console.log(data);
        });
}

如果 ngModel 不是来自 ngFor ,我知道如何做到这一点,是否有另一种方法可以从 textarea 获得没有 ngModel 的值?也许这是唯一的方法,或者如果我仍然可以使用 ngModel .

1 回答

  • 3

    Summary of current state

    首先,让我总结一下您的数据所在 . 您有一个名为 searchBoxCount 的一个或多个对象的列表 . 列表中的每个元素都是一个具有name属性的对象,因此您可以调用 let name = this.searchBoxCount[0].name; 来获取列表中第一个对象的名称 .

    在HTML模板中,您使用ngFor循环遍历 searchBoxCount 列表中的所有对象,并在每次迭代中将对象分配给名为 inputSearch 的本地(到ngFor)变量 . 然后,将每个循环迭代中创建的textarea的输入绑定到该迭代的 inputSearch 对象的 name 属性 .

    How to get your data

    这里的关键是 inputSearch 与在某个特定索引(第一个对象的索引0等)中存储在 searchBoxCount 中的对象相同 . 因此,当ngModel与 inputSearch.name 绑定时,它也与 searchBoxCount[n].name 相关 . 在ngFor的外部,您将遍历 searchBoxCount 列表以获取所需的每个名称 .

    As a consequence

    基于对原始帖子的评论,听起来您可以在查询字符串输出中包含一个或多个名称 . 这意味着你的 getQueryString() 工作,你必须遍历列表(或在这种情况下,让列表循环为我们):

    getQueryString() {
        this.isLoading = true;
        let result : string = "?id=";
        this.searchBoxCount.forEach(
            (inputSearch:any) => {  //Not the same variable, but same objects as in the ngFor
                result = result + inputSearch.name + "&id=";
        });
        result = result.slice(0, result.length - 4);  //trim off the last &id=
        return result;
    }
    

    Edit: Multiple different fields with different names

    从这篇文章的评论中可以看出,每个inputSearch都有自己的密钥用于查询字符串,该密钥存储在name属性中 . 您需要保留该名称,这意味着 can't 将ngModel绑定到它 . 否则,用户将通过键入自己的文本来销毁名称,并且无法获得正确的密钥 . 为此,您需要将ngModel绑定到inputSearch对象的其他属性 . 我将假设该对象具有value属性,所以它看起来像这样:

    {
        name: "id",
        value: "33\n44"
    }
    

    也就是说,每个inputSearch都有一个名称,该值将包含一个或多个值,用新行分隔 . 然后,您必须将HTML模板更改为:

    <div *ngFor="let inputSearch of searchBoxCount; let i = index" 
         [ngClass]="{'col-sm-3': swaggerParamLength=='3', 'col-sm-9': 
         swaggerParamLength=='1'}">
       <textarea name="{{inputSearch.name}}" 
                 id="{{inputSearch.name}}" rows="3" class="search-area-txt" 
                 attr.placeholder="Search Product {{inputSearch.name}}"
                 [(ngModel)]="inputSearch.value"></textarea>
    </div>
    

    请注意,我将ngModel从 inputSearch.name 更改为inputSearch?.value(如果没有值,则允许为null) inputSearch.value . 然后getQueryString()方法看起来像这样:

    getQueryString() {
        let result:string = "?";
    
        //for each of the input search terms...
        this.searchBoxCount.forEach( (inputSearch:any) => {
            // first reparse the input values to individual key value pairs
            let inputValues:string = inputSearch.value.split("\n")
                 .filter(function(str) { return str !== "" })
                 .join("&" + inputSearch.name + "=");
            // then add it to the overall query string for all searches
            result = result + 
                 inputSearch.name + 
                 "=" + 
                 inputValues +
                 "&"
        });
        // remove trailing '&'
        result = result.slice(0, result.length - 1);
        return result;
    }
    

    注意,使用RxJs这可能更容易,但我正在测试vanilla javascript .

    使用此功能,如果用户输入了两个ID(33和44),一个sku和两个电子邮件,结果将是 ?id=33&id=24&sku=abc123&email=name@compa.ny&email=an.other@compa.ny

相关问题