将 ControllerAs 与指令一起使用
Using ControllerAs with a Directive
我正在尝试遵循 John Papa 的 angularJS 风格指南 here 并开始将我的指令切换为使用 controllerAs。但是,这是行不通的。我的模板似乎无法访问分配给 vm 的任何内容。请参阅展示行为的这个非常简单的 plnkr 示例。
http://plnkr.co/edit/bVl1TcxlZLZ7oPCbk8sk?p=preview
angular
.module('app', []);
angular
.module('app')
.directive('test', test);
function test() {
return {
restrict: 'E',
template: '<button ng-click="click">{{text}}</button>',
controller: testCtrl,
controllerAs: 'vm'
}
}
angular
.module('app')
.controller('testCtrl', testCtrl);
function testCtrl() {
var vm = this;
vm.text = "TEST";
}
当使用 controllerAs 语法时,您不会像往常一样访问 $scope,变量 vm 被添加到范围中,因此您的按钮需要变为:
<button ng-click="click">{{vm.text}}</button>
注意 vm.
添加到 text
的开头。
Here is a fork of your Plunk with the fix applied
问:您知道我如何访问作为属性传递给指令的属性吗,例如 "scope: { text: '@' }"?然后我是否被迫在控制器上使用 $scope 并设置 vm.text = $scope.text?
答:在您引用的那篇文章中,a section y075 就是谈到了这种情况。查看 bindToController
:
return {
restrict: 'E',
template: '<button ng-click="click">{{text}}</button>',
controller: testCtrl,
controllerAs: 'vm',
scope: {
text: '@'
},
bindToController: true // because the scope is isolated
};
那么你应该可以访问vm.text
使用 "controllerAs",控制器实例别名 - vm
,在你的例子中 - 作为范围的 .vm
属性 在范围上发布。
因此,要访问其属性(即控制器的属性),您需要指定 {{vm.text}}
或 ng-click="vm.click"
。
当你使用 controllerAs 语法时,你必须使用
bindToController: true
它将在您的指令中起作用。
当使用'controllerAs'语法时,如上所述,范围绑定到控制器的'this'引用。
所以它允许我们引入一个新的命名空间('vm' 在这里)绑定到我们的控制器,而不需要将范围属性放在额外的对象文字中(比如 $scope).
因此访问控制器范围内的任何内容,需要 'vm' 命名空间,如,
'<button ng-click="click">{{vm.text}}</button>'
我知道这张票很旧了。我加了 0.02 美元,以防将来有人无意中发现这个问题。
首先,最好了解一下您要实现的目标的背景信息,因为您似乎违反了设计规则。你的指令不需要知道控制器的内部工作原理,或者 vice-versa.
我创建了一个简单的示例来说明如何在指令中设置按钮的标题。这里不需要控制器,我认为这只会让你的例子难以理解。
var myApp = angular.module('myApp', []);
myApp.directive('myDirective', function() {
return {
scope: {
caption: "@"
},
template: '<button>{{caption}}</button>'
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp">
<my-directive caption="Hello World" />
</div>
我正在尝试遵循 John Papa 的 angularJS 风格指南 here 并开始将我的指令切换为使用 controllerAs。但是,这是行不通的。我的模板似乎无法访问分配给 vm 的任何内容。请参阅展示行为的这个非常简单的 plnkr 示例。
http://plnkr.co/edit/bVl1TcxlZLZ7oPCbk8sk?p=preview
angular
.module('app', []);
angular
.module('app')
.directive('test', test);
function test() {
return {
restrict: 'E',
template: '<button ng-click="click">{{text}}</button>',
controller: testCtrl,
controllerAs: 'vm'
}
}
angular
.module('app')
.controller('testCtrl', testCtrl);
function testCtrl() {
var vm = this;
vm.text = "TEST";
}
当使用 controllerAs 语法时,您不会像往常一样访问 $scope,变量 vm 被添加到范围中,因此您的按钮需要变为:
<button ng-click="click">{{vm.text}}</button>
注意 vm.
添加到 text
的开头。
Here is a fork of your Plunk with the fix applied
问:您知道我如何访问作为属性传递给指令的属性吗,例如 "scope: { text: '@' }"?然后我是否被迫在控制器上使用 $scope 并设置 vm.text = $scope.text?
答:在您引用的那篇文章中,a section y075 就是谈到了这种情况。查看 bindToController
:
return {
restrict: 'E',
template: '<button ng-click="click">{{text}}</button>',
controller: testCtrl,
controllerAs: 'vm',
scope: {
text: '@'
},
bindToController: true // because the scope is isolated
};
那么你应该可以访问vm.text
使用 "controllerAs",控制器实例别名 - vm
,在你的例子中 - 作为范围的 .vm
属性 在范围上发布。
因此,要访问其属性(即控制器的属性),您需要指定 {{vm.text}}
或 ng-click="vm.click"
。
当你使用 controllerAs 语法时,你必须使用
bindToController: true
它将在您的指令中起作用。
当使用'controllerAs'语法时,如上所述,范围绑定到控制器的'this'引用。 所以它允许我们引入一个新的命名空间('vm' 在这里)绑定到我们的控制器,而不需要将范围属性放在额外的对象文字中(比如 $scope). 因此访问控制器范围内的任何内容,需要 'vm' 命名空间,如,
'<button ng-click="click">{{vm.text}}</button>'
我知道这张票很旧了。我加了 0.02 美元,以防将来有人无意中发现这个问题。
首先,最好了解一下您要实现的目标的背景信息,因为您似乎违反了设计规则。你的指令不需要知道控制器的内部工作原理,或者 vice-versa.
我创建了一个简单的示例来说明如何在指令中设置按钮的标题。这里不需要控制器,我认为这只会让你的例子难以理解。
var myApp = angular.module('myApp', []);
myApp.directive('myDirective', function() {
return {
scope: {
caption: "@"
},
template: '<button>{{caption}}</button>'
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp">
<my-directive caption="Hello World" />
</div>