我正在写一个简单的角度组件。我将参数作为绑定传递并在屏幕上显示其值。一切正常:我可以看到屏幕上显示的参数。
组件:
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>"
});
HTML:
<test contact-id="8"></test>
但是,当我尝试从控制器中访问绑定时(请参阅console.log),绑定值为undefined
。我不明白它在视图中是如何可用的,而不是在控制器中。
我做错了什么?
这是一个说明问题的plnkr。
答案 0 :(得分:51)
使用角度组件时,控制器尚未通过内部链接进行连接。如果您尝试在控制器的构造函数中执行此操作,则表示您尚未将链接绑定到绑定。 Component API公开了一些你可以定义的生命周期钩子,它会在特定时间触发。您正在寻找$onInit
挂钩。
$ onInit() - 在构造了元素上的所有控制器并初始化其绑定之后(在此元素上的指令的pre&amp; post链接函数之前),在每个控制器上调用。这是为控制器放置初始化代码的好地方。
答案 1 :(得分:20)
确保在HTML和camelCase中使用连字符进行绑定,以便在Javascript中进行绑定。
app.component("test", {
bindings: {
"myContactId": "<"
}
}
<test my-contact-id="8"></test>
这就是我一直忘记做的事情。
答案 2 :(得分:7)
(Get-Content my.json) -replace '(?<pre>"version"[\s]*:[\s]*)(?<V>"[^\"]*")', '$1"$version"' | Out-File my.json
的值可在控制器的contactId
上找到:
$scope
链接到另一个版本的Plunker here。
答案 3 :(得分:6)
关键字此似乎不适用于箭头功能,这适用于
controller: function() {
alert('contact id from controller: ' + this.contactId);
}
使用箭头功能时,这个,似乎是指窗口对象,因为
箭头函数不会创建它自己的上下文,而是它 捕获封闭上下文的这个值
答案 4 :(得分:4)
我会建议你做一些改变,以避免这些不寻常的错误。
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>
一些观点:
将绑定传递给html中的组件始终是kebab cased ex my-contact-id,其各自的javascript变量将是cammal cased:myContactId。
如果您传递了对象使用的值,请使用&#39; @&#39;在绑定中。 如果您正在使用对象并将对象传递给bindigs,请使用&#39;&lt;。 如果你想要对该对象进行双向绑定,请使用&#39; =&#39;在bindings config
bindings:{ value:'@', object:'<', // also known as one-way twoWay:'=' }
答案 5 :(得分:1)
它可能不是最佳做法,但您可以轻松访问这些值:
$scope.$ctrl.contactId
您可以在$ scope内的$ ctrl属性中获取所有绑定。
我希望得到它的帮助
答案 6 :(得分:0)
对于那些使用指令的人,如果指定了组件,如果指定了绑定{},则会将相同的参数添加到范围{}中:
/*bindings: {
modalInstance: '<',
resolve: '<'
},*/
scope: {
modalInstance: '<',
resolve: '<'
},
*在我写完上面的内容之后发现,在我从$ scope.resolve分配它之前,$ scope上没有另外的范围参数foo可用。所以我必须在$ scope.init()中执行此操作:$ scope.foo = $ scope.resolve.foo。不知道为什么。猜测它与我的UI Bootstrap Modal + Directives用法有关
对于其他人来说,这可能是显而易见的,但对于我来说,对于AnguluarJS来说,这并不是一个新手。
我的问题是使用带有UI-Bootstrap Modals的Directives,它与Directives兼容,但设计和记录用于组件。
答案 7 :(得分:0)
我将为@jusopi和接受的答案添加另一个答案,仅针对可能遇到我问题的人。关于组件,即使在经过$onInit
钩之后,我的数据仍然为null,因为仍然没有收到来自服务器的值。为了解决这个问题(尽管可能有更好的方法来处理这种情况),我还利用了$onChanges
钩子。 $onChanges
将返回传递时已更改的数据,您可以解析该信息,或者简单地将绑定称为this.contactId
并将其更新。
documentation中提供了更多详细信息:https://docs.angularjs.org/guide/component
答案 8 :(得分:0)
代码存在两个问题,导致“未定义”错误。
摘自官方文档:AngularJs Documentation
$ onInit()-在一个控制器上的所有控制器之后,在每个控制器上调用 元素已构造并已初始化其绑定(和 在此之前和之后链接功能的指令之前 元件)。这是放置初始化代码的好地方 控制器。
问题在于箭头表示法没有它自己的作用域,而是使用它的封闭作用域。 意味着使用“ this”时将引用窗口对象而不是组件。 因此调用this。$ onInit()将在窗口上调用,并且不会被触发,因为它在窗口上不存在。