带有动态表达式的 ng-options 不起作用
ng-options with a dynamic expression is not working
我正在尝试创建一个 directive
角度的,以替换常规下拉菜单。我需要能够将动态表达式设置为 ng-options
但似乎在指令中不起作用。
它在外面工作得很好。
这是指令
angular.module('app.dropdown',[])
.directive('swDropdown',[ function ( ){
return {
restrict: 'E',
replace: true,
template:'<div><select ng-model="swModel" ng-options="{{expression}}" ></div>',
link: link,
scope:{
swOptions:"=",
swLabel:'@',
swValue:'@',
swModel:"="
}
};
function link (scope, element, attrs) {
scope.defaultText = angular.isDefined(attrs.swDefaultText)?attrs.swDefaultText:'Choose';
scope.selected = scope.defaultText;
scope.expression = 'item as item.name for item in swOptions';
}
}]);
控制器示例:
angular.module('app',['app.dropdown']).controller('Ctrl', function($scope){
$scope.model="";
$scope.expression = 'item as item.name for item in options';
$scope.options = [
{id:1,name:'hola'},
{id:2,name:'chau'}]
});
HTML:
<body ng-app="app" ng-controller="Ctrl">
<h1>Hello Plunker!</h1>
Working dropdown<br/>
<select ng-model="model" ng-options="{{expression}}"></select>
<br/>
Not working inside a directive
<sw-dropdown sw-model="model" sw-options="options"></sw-dropdown>
</body>
关于为什么它不起作用的任何线索?
谢谢!
这是因为您有一个独立的作用域,因此 ngOptions 无法正确输入该值
将您的模板更改为
template:'<div><select ng-model="swModel" ng-options="item as item.name for item in swOptions"></div>',
编辑:如果你真的想传递一个节点,你需要在编译函数中进行,因为那是 ngOptions 指令编译它们的时候。
angular.module('app.dropdown',[])
.directive('swDropdown',[ function ( ){
return {
restrict: 'E',
replace: true,
template:'<div><select ng-model="swModel" ng-options="{{expression}}" ></div>',
compile: compile,
scope:{
swOptions:"=",
swLabel:'@',
swValue:'@',
swModel:"="
}
};
function compile(cElement, cAttributes, transclude){
return {
pre: function(scope, element, attrs){
scope.expression = 'item as item.name for item in swOptions';
},
post: function(scope, element, attrs){
scope.defaultText = angular.isDefined(attrs.swDefaultText)?attrs.swDefaultText:'Choose';
scope.selected = scope.defaultText;
}
}
}
}]);
这是个好问题。归根结底,ng-options
需要在 Angular 处理 <select>
时有一个值。
1) 您可以在"pre-link"函数中设置:
.directive('swDropdown',[function (){
return {
...
link: {
pre: function(scope){
scope.expression = "item as item.name for item in swOptions";
},
post: // your normal link function
}
}
}]);
2) 或者,如果你很懒,你可以在模板中添加 ng-if="expression"
,并保持一切不变:
.directive('swDropdown',[function (){
return {
...
template: '<div><select ng-if="expression" ng-model="swModel" ng-options="{{expression}}"></select></div>',
link: link // this is treated as post-link
}
function link(scope, element){
// ...
}
}]);
3) 如果你的表达式确实需要可变和修改(看起来很奇怪,应该用更合适的 ViewModel 来解决),那么你需要强制重新编译:
function link(scope, element){
...
scope.changeExpression = function(newExpression){
scope.expression = newExpression;
// $compile should be injected into your directive's function
$compile(element)(scope);
}
}
顺便说一句,只需将 $compile(element)(scope);
添加到您当前的 link 函数即可。
我正在尝试创建一个 directive
角度的,以替换常规下拉菜单。我需要能够将动态表达式设置为 ng-options
但似乎在指令中不起作用。
它在外面工作得很好。
这是指令
angular.module('app.dropdown',[])
.directive('swDropdown',[ function ( ){
return {
restrict: 'E',
replace: true,
template:'<div><select ng-model="swModel" ng-options="{{expression}}" ></div>',
link: link,
scope:{
swOptions:"=",
swLabel:'@',
swValue:'@',
swModel:"="
}
};
function link (scope, element, attrs) {
scope.defaultText = angular.isDefined(attrs.swDefaultText)?attrs.swDefaultText:'Choose';
scope.selected = scope.defaultText;
scope.expression = 'item as item.name for item in swOptions';
}
}]);
控制器示例:
angular.module('app',['app.dropdown']).controller('Ctrl', function($scope){
$scope.model="";
$scope.expression = 'item as item.name for item in options';
$scope.options = [
{id:1,name:'hola'},
{id:2,name:'chau'}]
});
HTML:
<body ng-app="app" ng-controller="Ctrl">
<h1>Hello Plunker!</h1>
Working dropdown<br/>
<select ng-model="model" ng-options="{{expression}}"></select>
<br/>
Not working inside a directive
<sw-dropdown sw-model="model" sw-options="options"></sw-dropdown>
</body>
关于为什么它不起作用的任何线索?
谢谢!
这是因为您有一个独立的作用域,因此 ngOptions 无法正确输入该值
将您的模板更改为
template:'<div><select ng-model="swModel" ng-options="item as item.name for item in swOptions"></div>',
编辑:如果你真的想传递一个节点,你需要在编译函数中进行,因为那是 ngOptions 指令编译它们的时候。
angular.module('app.dropdown',[])
.directive('swDropdown',[ function ( ){
return {
restrict: 'E',
replace: true,
template:'<div><select ng-model="swModel" ng-options="{{expression}}" ></div>',
compile: compile,
scope:{
swOptions:"=",
swLabel:'@',
swValue:'@',
swModel:"="
}
};
function compile(cElement, cAttributes, transclude){
return {
pre: function(scope, element, attrs){
scope.expression = 'item as item.name for item in swOptions';
},
post: function(scope, element, attrs){
scope.defaultText = angular.isDefined(attrs.swDefaultText)?attrs.swDefaultText:'Choose';
scope.selected = scope.defaultText;
}
}
}
}]);
这是个好问题。归根结底,ng-options
需要在 Angular 处理 <select>
时有一个值。
1) 您可以在"pre-link"函数中设置:
.directive('swDropdown',[function (){
return {
...
link: {
pre: function(scope){
scope.expression = "item as item.name for item in swOptions";
},
post: // your normal link function
}
}
}]);
2) 或者,如果你很懒,你可以在模板中添加 ng-if="expression"
,并保持一切不变:
.directive('swDropdown',[function (){
return {
...
template: '<div><select ng-if="expression" ng-model="swModel" ng-options="{{expression}}"></select></div>',
link: link // this is treated as post-link
}
function link(scope, element){
// ...
}
}]);
3) 如果你的表达式确实需要可变和修改(看起来很奇怪,应该用更合适的 ViewModel 来解决),那么你需要强制重新编译:
function link(scope, element){
...
scope.changeExpression = function(newExpression){
scope.expression = newExpression;
// $compile should be injected into your directive's function
$compile(element)(scope);
}
}
顺便说一句,只需将 $compile(element)(scope);
添加到您当前的 link 函数即可。