【发布时间】:2015-03-23 04:19:46
【问题描述】:
我是 AngularJS 的新手。我尝试使用选项 transclude=true 创建指令,但它似乎破坏了 $scope。这是我的代码:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script>
<script type="text/javascript">
var app = angular.module('myApp', []);
app.controller('myController', ['$scope', function($scope){
$scope.myText = 'Hello';
$scope.facility = null;
$scope.facilities = [
{id:1, name:'One'},
{id:2, name:'Two'},
{id:3, name:'Three'}
];
$scope.query = function(){
console.log($scope.facility, $scope.myText);
}
}]);
app.directive('ohMy', function(){
return {
transclude: true,
template: function(){
return '<form novalidate><div ng-transclude></div></form>';
}
}
});
</script>
</head>
<body>
<div ng-controller="myController">
<oh-my>
<input type="text" ng-model="myText"></input>
<div>{{myText}}</div>
<select ng-change="query()" ng-model="facility" ng-options="f.name for f in facilities"></select>
</oh-my>
</div>
</body>
</html>
当我更改文本框值 (myText) 时,文本框下一个 div 内的文本显示更新后的值,正如我预期的那样。但不是当我使用下拉菜单时——浏览器的控制台总是显示默认值。
当我删除此指令后,一切正常。
我在创建指令时做错了什么?有什么办法解决吗?
-- 更新--
google了一阵子,找到了这个链接:AngularJS transclude but keep the directive's scope并尝试理解,然后我将指令代码修改成这样:
app.directive('ohMy', function(){
return {
transclude: true,
template: function(){
return '<form novalidate><div ng-transclude></div></form>';
},
link: function(scope, element, attrs, ctrl, transclude) {
transclude(scope, function(clone) {
element.children(0).empty().append(clone);
});
}
}
});
它现在按我的预期工作。但是,有更好的解决方案吗?
【问题讨论】:
-
是的,这是点规则。您的模型
facility应该嵌套在一个对象中。该指令创建了一个子范围,此时您正在使用两个不同的$scope.facility属性,因为该值是一个原始值。如果你做foo.facility,子作用域将继承foo,然后facility必须是相同的。 -
谢谢,m59!它与点一起工作。但正如你所说,这是“规则”,这是我们无法避免的吗?我的意思是这个指令中的模型必须是一个嵌套对象?
-
有些人假装 $scope 继承不存在并在所有指令上放置隔离作用域,然后将数据显式传递给指令。
标签: javascript angularjs angularjs-directive