为什么uib-typeahead方法的参数必须是键值对?

时间:2017-11-08 14:28:55

标签: angularjs typescript angular-ui-bootstrap

为什么我需要将$viewValue放在下面示例中的键值对中(使用Angular 1.6.2和Typescript)?

export class PageHeaderComponent implements ng.IComponentOptions {
    public template: string = `
    // ... other markup omitted
    <input type="text"
       name="search" 
       class="form-control text-field"
       placeholder="{{$ctrl.searchPlaceholder}}"
       ng-model="$ctrl.search"
       uib-typeahead="item for item in $ctrl.getItems({value: $viewValue})"
     />
   ...
   public bindings: any = {
    headerTitle: "<",
    showBackButton: "<",
    entityName: "<",
    addAction: "&",
    adding: "<",
    search: "=",
    searchPlaceholder: "<",
    getItems: "&"
  };
}

PageHeader组件包含在LandingPage组件中。 getItemsLandingPage控制器上的方法。

export class LandingPageComponent implements ng.IComponentOptions {
    public template: string = `
    <div class="landing-page">
        <page-header 
            header-title="'Businesses'"
            add-action="$ctrl.showAddBusiness()"
            entity-name="'Business'"
            search-placeholder="'Search for a business'"
            search="$ctrl.search.name"
            adding="$ctrl.adding",
            get-items="$ctrl.getItems({value})"
            ></page-header>
   // ... other markup omitted
   `;

    public controller: any = LandingPageComponentController;
}

export class LandingPageComponentController {

  // ... Irrelevant details omitted 

   public getItems(value: {value}): Promise<string[]> {
      return new Promise((resolve, reject) => {
            resolve(["one", "two", "three", "four"]);
      });
  }
}

如果我只是简单地传递$viewValue(并将getItems的签名更改为getItems(value: string),则会收到此错误:

TypeError: Cannot use 'in' operator to search for '$ctrl' in o

显然,能够修复错误,我只是想了解为什么我的修复有效。

1 个答案:

答案 0 :(得分:1)

这不是uib-typeahead,而是在LandingPageComponent和{{1}之间使用输出事件绑定(&#39;&amp;&#39;) }。

您实际上可以稍微简化一下代码:

PageHeaderComponent模板中:

LandingPageComponent

get-items="$ctrl.getItems(value)"

LandingPageComponentController

为什么?

  • 使用&#39;&amp;&#39;将表达式传递给子组件时绑定,表达式不会被评估,直到子组件调用它。
  • 虽然子组件调用了表达式,但它会在父范围内进行评估。
  • 这个表达式不知道子组件中发生了什么 - 所以它不知道存在的变量/值。
  • AngularJS如何解决这个问题?可以把它想象成AngularJS,使用你传递给绑定的对象(当你调用它时)来创建局部变量&#39;用。评估表达式。

所以在public getItems(value: string): Promise<string[]> { return new Promise((resolve, reject) => { resolve(["one", "two", "three", "four"]); }); } ,当你去:

PageHeaderComponent

考虑AngularJS为$ctrl.getItems({value: $viewValue}) 执行此操作:

LandingPageComponent

实际情况并非如此,但我认为它应该可以帮助您理解为什么我们需要传回一个对象(而不是直接传递值)

这篇文章非常好地描述了为什么我们需要以这种方式处理输出事件:

http://www.codelord.net/2016/05/13/understanding-angulars-and-binding/