TranscludeScope 中的控制器 $scope 和 <form>
Controller $scope and <form> in TranscludeScope
我有一个包含嵌入的指令。嵌入的内容是一个表单,它有一个提交选项调用(父)控制器中的一个方法。此方法是从嵌入范围调用的,因此我在控制器中访问的任何变量都可以通过 this.variable
访问,因为这反映了调用者(当前)范围。但是,$scope.variable
是未定义的,因为 $scope
是父作用域,即控制器的作用域。
我真的应该使用 this
来访问表单值,还是有一个约定我应该实施以通过(父)控制器中的 $scope
进行访问?
免责声明:我知道我没有使用 controllerAs 功能,现在我无法为项目更改它。
Plunker 演示问题:
http://plnkr.co/edit/TdgZFIRNbUcHNfe3a7uO?p=preview
如您所见,当您更改文本框中的值时,指令中的值会更新。这是预期的,因为两者都引用了包含的范围。指令外的 {{name}}
不会改变,因为这是父范围而不是被嵌入的范围。单向交通。
正确的解决方法是什么?使用 this.name
或修改指令,以便 $scope.name
可以在指令外使用?
对于那些喜欢代码而不是笨蛋的人:
HTML:
<body ng-app="docsTransclusionExample">
<div ng-controller="Controller">
{{name}}
<my-dialog>
Check out the contents, {{name}}!
<form>
<input ng-model="name">
</form>
</my-dialog>
</div>
</body>
指令:
(function(angular) {
'use strict';
angular.module('docsTransclusionExample', [])
.controller('Controller', function($scope) {
$scope.name = 'Tobias';
})
.directive('myDialog', function() {
return {
restrict: 'E',
transclude: true,
scope: {},
templateUrl: 'my-dialog.html'
};
});
})(window.angular);
指令模板:
<div class="alert" ng-transclude></div>
这与 angular 中的 "The Dot Rule" 有关。
这意味着,当您具有作用域层次结构时,子作用域试图修改父作用域,它正在创建自己的作用域。
当您使用数据对象时,您访问成员 "with a dot",因此您不会直接更改作用域,也不会创建新的子作用域
你的情况
$scope.name = 'Tobias';
应该改为
$scope.data = {name: 'Tobias'};
查看插件:
http://plnkr.co/edit/RqORVm8r4jph532dT6nY?p=preview
进一步阅读:
Why don't the AngularJS docs use a dot in the model directive?
https://www.youtube.com/watch?v=DTx23w4z6Kc
PS.
- 这与指令嵌入无关(这是关于构建 DOM)。
- 如果您这样做:
scope: {}
在指令中,您明确地创建了一个子作用域。
我有一个包含嵌入的指令。嵌入的内容是一个表单,它有一个提交选项调用(父)控制器中的一个方法。此方法是从嵌入范围调用的,因此我在控制器中访问的任何变量都可以通过 this.variable
访问,因为这反映了调用者(当前)范围。但是,$scope.variable
是未定义的,因为 $scope
是父作用域,即控制器的作用域。
我真的应该使用 this
来访问表单值,还是有一个约定我应该实施以通过(父)控制器中的 $scope
进行访问?
免责声明:我知道我没有使用 controllerAs 功能,现在我无法为项目更改它。
Plunker 演示问题: http://plnkr.co/edit/TdgZFIRNbUcHNfe3a7uO?p=preview
如您所见,当您更改文本框中的值时,指令中的值会更新。这是预期的,因为两者都引用了包含的范围。指令外的 {{name}}
不会改变,因为这是父范围而不是被嵌入的范围。单向交通。
正确的解决方法是什么?使用 this.name
或修改指令,以便 $scope.name
可以在指令外使用?
对于那些喜欢代码而不是笨蛋的人:
HTML:
<body ng-app="docsTransclusionExample">
<div ng-controller="Controller">
{{name}}
<my-dialog>
Check out the contents, {{name}}!
<form>
<input ng-model="name">
</form>
</my-dialog>
</div>
</body>
指令:
(function(angular) {
'use strict';
angular.module('docsTransclusionExample', [])
.controller('Controller', function($scope) {
$scope.name = 'Tobias';
})
.directive('myDialog', function() {
return {
restrict: 'E',
transclude: true,
scope: {},
templateUrl: 'my-dialog.html'
};
});
})(window.angular);
指令模板:
<div class="alert" ng-transclude></div>
这与 angular 中的 "The Dot Rule" 有关。
这意味着,当您具有作用域层次结构时,子作用域试图修改父作用域,它正在创建自己的作用域。
当您使用数据对象时,您访问成员 "with a dot",因此您不会直接更改作用域,也不会创建新的子作用域
你的情况
$scope.name = 'Tobias';
应该改为
$scope.data = {name: 'Tobias'};
查看插件: http://plnkr.co/edit/RqORVm8r4jph532dT6nY?p=preview
进一步阅读:
Why don't the AngularJS docs use a dot in the model directive?
https://www.youtube.com/watch?v=DTx23w4z6Kc
PS.
- 这与指令嵌入无关(这是关于构建 DOM)。
- 如果您这样做:
scope: {}
在指令中,您明确地创建了一个子作用域。