如果我使用$ scope,这个指令可以完美地运行:
function alertBox(){
return {
template:
'<div ng-show="alert" class="alert alert-{{alert.type}}" style="text-align: center;">\
<a href="#" class="close" data-dismiss="alert" aria-label="close" title="close">x</a>\
<span ng-bind-html="alert.message | safe_html"></span>\
</div>'
}
}
警报在我的控制器中定义为:
$scope.alert = {message: 'test!', type: 'danger'};
我的简单观点:
<div alert-box></div>
但是,我不使用$ scope,而是使用'this'定义警报:
this.alert = {message: 'test!', type: 'danger'};
但无论我尝试什么,我都无法弄清楚如何将'this'的值注入指令。
理想情况下,我可以引用'self.alert'或其他东西,这样我就不必将范围上下文定义为属性,但假设我这样做,我尝试过这种变化无济于事:
function alertBox(){
return {
scope: {
scope: '=scope'
},
template: '<div ng-show="' + scope + '.alert" class="alert alert-' + scope + '.type" style="text-align: center;"><a href="#" class="close" data-dismiss="alert" aria-label="close" title="close">x</a> <span ng-bind-html="' + scope + '.message | safe_html"></span></div>'
}
}
我的HTML:
<div alert-box scope="welcome"></div>
在那个例子中,我已经定义了'WelcomeController as welcome'
。
感谢任何帮助。
答案 0 :(得分:2)
这里有几个误解的问题。
首先,具有自己模板的指令通常使用隔离范围,这样模板操作的范围与指令操作的范围不同。这就是使指令可重复使用的原因。
在您的原始示例中,该指令使用父作用域(带有隐式scope: false
)而不是隔离作用域(scope: {}
)。
第二次,您尝试将&#34;控制器用作&#34;接近并将alert
对象定义为控制器实例的属性。然后,控制器实例(您称之为this
)将在示例中的控制器别名 - welcome
下的范围内发布。因此,您需要{{alert.message}}
而不是{{welcome.alert.message}}
。这就是&#34;控制器作为&#34;确实 - 把这个&#34;这个&#34; (即控制器实例对象)为$scope.<alias>
。
所以(并且仍然),适用范围的原则,如我的第一点所述,适用。
===
为了使您的示例有效,请使用isolate scope创建一个指令,并通过属性绑定绑定对象alert
。
以下是规范(虽然浪费,见下文)这样做的方式:
.directive("alertBox", function(){
return {
scope: {
alert: "="
},
template: '<div ng-show="alert" class="alert-{{alert.type}}">{{alert.message}}</div>'
};
})
用法:
<div ng-controller="WelcomeController as welcome">
<div alert-box alert="welcome.alert"></div>
</div>
// in WelcomeController
this.alert = {message: 'test!', type: 'danger'};
指令的模板不受在作用域上设置传入的alert
对象的影响。
红利部分
那么,为何浪费?
"="
范围绑定会创建双向绑定,这在此处可能是不必要的,因为预期指令alertBox
不会修改父级的alert
对象。双向绑定设置2个观察者,其中一个未使用,因此浪费。
相反,您可以使用"&"
单向绑定到表达式。 "&"
提供了一个函数,需要调用它来获取绑定表达式返回的对象(而不是直接与"="
一样的对象),因此指令的模板稍微改变为: / p>
scope: {
alert: "&",
},
template: '<div ng-show="alert()" class="alert-{{alert().type}}">{{alert().message}}</div>'
答案 1 :(得分:-1)
bindToController:您可以使用bindToController属性,当在范围隔离的指令中设置为true时,组件属性绑定到controller
而不是scope
,这使得它可以在this
上找到。
通常,在使用controller as
语法时,您会执行类似的操作。
var myapp = angular.module('myapp', []);
myapp.controller('MainCtrl', function () {
this.name = "Vinoth Babu";
});
myapp.directive('alertBox', function(){
return {
controller: 'MainCtrl',
controllerAs: 'ctrl',
bindToController: true,
template: '<div>{{ctrl.name}}</div>'
};
});
HTML代码段
<div ng-app="myapp">
<div ng-controller="MainCtrl as ctrl">
<div alert-box></div>
</div>
</div>
工作小提琴:http://jsfiddle.net/SNF9x/136/
如果你有别的想法,请告诉我。