为什么我的组件绑定在其控制器中未定义?

fik*_*tra 60 javascript angularjs angularjs-1.5

我正在写一个简单的角度组件.我将参数作为绑定传递并在屏幕上显示其值.一切正常:我可以看到屏幕上显示的参数.

零件:

var app = angular.module("test", []);
app.component("test", {
  bindings: {
    "contactId": "<"
  },
  controllerAs: "model",
  controller: () => {
    //output: 'contact id from controller: undefined'
    console.log(`contact id from controller: ${this.contactId}`);
  },
  template: "<div>Contact id from view: {{model.contactId}}</div>"
});
Run Code Online (Sandbox Code Playgroud)

HTML:

<test contact-id="8"></test>
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试从控制器中访问绑定时(请参阅console.log),绑定值为undefined.我不明白它在视图中是如何可用的,而不是在控制器中.

我究竟做错了什么?

这是一个解释问题的方法.

jus*_*opi 54

使用角度组件时,控制器尚未通过内部链接连接.如果您尝试在控制器的构造函数中执行此操作,则尚未链接到绑定.Component API公开了一些你可以定义的生命周期钩子,它会在特定时间触发.你正在寻找$onInit钩子.

$ onInit() - 在构造了元素上的所有控制器并初始化其绑定之后(在此元素上的指令的前后链接函数之前),在每个控制器上调用.这是为控制器放置初始化代码的好地方.

每个文档 - https://docs.angularjs.org/guide/component

  • 在某些情况下,您的绑定可以在以后更新,并且在调用钩子`$ onInit`时它的值没有准备好.在这种情况下,您应该使用`$ onChanges`并跳过第一个更改.工作示例:https://jsfiddle.net/auxcoder/4hq5gaq0/ (6认同)
  • @aUXcoder那是我的问题.我试图在绑定到组件的数据准备好之前创建组件.放置一个`ng-if`指令以确保在组件初始化之前我有数据(例如`<custom-component ng-if ="!$ ctrl.data"data ="$ ctrl.data"> </ custom-组件>`)修复了问题. (3认同)

kol*_*bok 29

确保在HTML和camelCase中使用连字符进行绑定,以便在Javascript中进行绑定.

app.component("test", {
  bindings: {
    "myContactId": "<"
  }
}

<test my-contact-id="8"></test>
Run Code Online (Sandbox Code Playgroud)

这就是我一直忘记做的事情.


Joh*_*der 7

值在控制器中contactId可用$scope:

var app = angular.module("test", []);
app.component("test", {
  bindings: {
    "contactId": "<"
  },
  controllerAs: "model",
  controller: ($scope) => {
    var model = $scope.model;
    alert(`contact id from controller: ${model.contactId}`);
  },
  template: "<div>Contact id from view: {{model.contactId}}</div>"
});
Run Code Online (Sandbox Code Playgroud)

链接到您的Plunker的另一个版本在这里.


Oli*_*ssé 6

关键字this似乎不适用于箭头功能,这适用于

controller: function() {
   alert('contact id from controller: ' + this.contactId);
}
Run Code Online (Sandbox Code Playgroud)

当使用箭头功能时,似乎是指窗口对象,因为

箭头函数不会创建它自己的这个上下文,而是捕获封闭上下文的this值


han*_*man 5

我将建议您真正需要避免这些不寻常的错误的一些更改。

app.component("test", {
  bindings: {
    "myContactId": "<"
  },
  controller:function(){
   var self=this;
   this.$onInit=function(){
    // do all your initializations here.
    // create a local scope object for this component only. always update that scope with bindings. and use that in views also.

       self.myScopeObject=self.myContactId
   }
  },
   template:'<p>{{$ctrl.myScopeObject}}</p>'
 }

<test my-contact-id="8"></test>
Run Code Online (Sandbox Code Playgroud)

几点:

  1. 将绑定传递到 html 中的组件总是会以 kebab 大小写 ex my-contact-id 并且其各自的 javascript 变量将是 cammal 大小写:myContactId。

  2. 如果要传递对象的值,请在绑定中使用“@”。如果您正在使用一个对象并将该对象传递给 bindigs,请使用 '<. 如果您想对该对象进行 2 路绑定,请在绑定配置中使用“=”

 bindings:{
      value:'@',
      object:'<', // also known as one-way
      twoWay:'='
    }
Run Code Online (Sandbox Code Playgroud)