似乎我对指令中孤立的范围感到困惑,希望你能帮助我。
我尝试将一段代码(包含一些自定义指令)包装到一个新指令中以减少代码重复。显然,我需要将一些属性(如ng-model
)作为参数赋予我的新指令,以使指令可重用。 ng-model
虽然不喜欢表达式(我最初尝试过ng-model="{{myVariableWhichContainsDesiredNgModelString}}"
),因此我最终得到了这篇文章:AngularJS - Create a directive that uses ng-model。
虽然接受的答案似乎适用于简单的设置,但我从接受的答案编辑了plunker以测试它是否也适用于嵌套指令:(在我的应用程序中,我需要包装来自第三方的指令 - 我无法编辑的图书馆)Plunker。在我的代码中,每个指令似乎都生成了自己的作用域,并且在作用域定义中使用=
进行双向数据绑定似乎并没有按照需要进行。
编辑:由于我不知道我在问什么,我编辑了上面的Plunker并将重新解释这个问题:在Plunker中我有三个输入字段,它们应该绑定到同一个模型-值。这最初是有效的,但是一旦我编辑第三个输入字段,它就会在其隔离的范围内生成自己的变量,而不是更新初始值。显然,第三个输入字段是指从该点开始的新变量。如何避免这种行为并将输入保持链接到$scope.model.name
?
观察:从模板中删除isolated-scope-directive会使一切按预期工作......
template: '<div><my-input ng-model="myDirectiveVar"></my-input></div>',
而不是
template: '<div><my-isolated-scope-directive><my-input ng-model="myDirectiveVar"></my-input></my-isolated-scope-directive></div>',
HTML:
<!-- this binds to the model which i would like all my inputs to bind to.-->
<input ng-model="name">
<!-- Example 1: This seems to generate a new modelvalue in the isolated-scope directive. Can I avoid this without modifying that directive?-->
<my-isolated-scope-directive><my-input ng-model="name"></my-input></my-isolated-scope-directive>
<!-- Example 2: This is what i would like my code to look like in the end: One directive which uses the code-snippet of Example 1 as template and passes some parameters into that template.-->
<my-wrapper-directive my-directive-var="name"></my-wrapper-directive>
指令:
my-input
包含修改后的输入字段:
app.directive('myInput', function() {
return {
restrict: 'E',
replace: true,
require: 'ngModel',
template: '<input class="some">',
link: function($scope, elem, attr, ctrl) {
console.debug($scope);
}
};
})
my-isolated-scope-directive
是一个占位符指令,它有自己的独立范围来模拟嵌套指令的行为:
.directive('myIsolatedScopeDirective', function() {
return {
restrict: 'E',
transclude: true,
replace: true,
scope: {
something: '='
},
template: '<div ng-transclude></div>',
link: function($scope, elem, attr, ctrl) {
console.debug($scope);
}
};
})
my-wrapper-directive
封装了前两个指令并接受了一个参数,该参数应该用作输入字段的ng-model值:
.directive('myWrapperDirective', function() {
return {
restrict: 'E',
transclude: false,
replace: true,
scope: {
myDirectiveVar: '='
},
template: '<div><my-isolated-scope-directive><my-input ng-model="myDirectiveVar"></my-input></my-isolated-scope-directive></div>',
link: function($scope, elem, attr, ctrl) {
console.debug($scope);
}
};
});
对我所缺少的任何建议和提示表示赞赏。我是否可以某种方式将ng-model
链接到服务实例而不使我的指令依赖于该服务?
答案 0 :(得分:2)
我不会这样做,因为它是使用范围的旧记法...我会使用controllerAs和bindToController
脚本:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function() {
this.model = { name: 'World' };
this.name = "Felipe";
});
app.directive('myInput', function() {
return {
restrict: 'E',
replace: true,
// controllerAs: 'app',
require: 'ngModel',
template: '<input class="some">',
controller: function(){
}
};
})
.directive('myIsolatedScopeDirective', function() {
return {
restrict: 'E',
transclude: true,
controllerAs: 'app1',
bindToController: {
something: '='
},
template: '<div ng-transclude></div>',
controller: function(){
}
};
})
.directive('myWrapperDirective', function() {
return {
restrict: 'E',
transclude: false,
controllerAs: 'app2',
bindToController: {
myDirectiveVar: '='
},
template: '<div><my-isolated-scope-directive>'+
'<my-input ng-model="app2.myDirectiveVar"></my-input>'+
'</my-isolated-scope-directive></div>',
controller: function(){
}
};
});
指数:
<!doctype html>
<html ng-app="plunker" >
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="style.css">
<script>document.write("<base href=\"" + document.location + "\" />");</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl as main">
This scope value
<input ng-model="main.model.name">
<my-isolated-scope-directive>
<my-input ng-model="main.model.name"></my-input>
</my-isolated-scope-directive>
<my-wrapper-directive my-directive-var="main.model.name">
</my-wrapper-directive>
</body>
</html>
查看plunker: http://plnkr.co/edit/VD0wXO1jivQc3JvfQFTh?p=preview
UPDATE 是的,好点,所以如果你想使用controllerAs,你需要角度1.2最小,对于bindToController你需要角度1.3