ng-options with a dynamic expression is not working

不问归期 提交于 2019-12-25 04:44:42

问题


I'm trying to create a directive in angular, to replace the regular dropdown. I need to be able to set a dynamic expression to ng-options but doesn't seem to be working inside the directive.

It works perfectly outside it.

This is the directive

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';


    }
}]);

Controller example:

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>

This is the example

Any clue about why it is not working?

Thanks!


回答1:


This is a good question. At the end of the day, ng-options needs to have a value when <select> is being processed by Angular.

1) You can either set it up in the "pre-link" function:

.directive('swDropdown',[function (){
   return {
     ...
     link: {
         pre: function(scope){
            scope.expression = "item as item.name for item in swOptions";
         },
         post: // your normal link function
     }
   }
}]);

2) Or, if you are lazy, you could just add ng-if="expression" to the template, and keep everything the same:

.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) if your expression is truly needs to be mutable and modifyable (seems like a weird case and should probably be address with a more suitable ViewModel), then you'd need to force re-compilation:

function link(scope, element){
   ...
   scope.changeExpression = function(newExpression){
     scope.expression = newExpression;

     // $compile should be injected into your directive's function
     $compile(element)(scope);
   }
}

Btw, just adding $compile(element)(scope); to your current link function would do the trick.




回答2:


This is because you have an isolated scope and thus ngOptions does not feed in this value properly

Change ur template to

template:'<div><select  ng-model="swModel" ng-options="item as item.name for item in swOptions"></div>',

Edit: if you really want to pass a node you need to do it in the compile function because thats when the ngOptions directive compiles them.

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;
        }
      }
    }
}]);


来源:https://stackoverflow.com/questions/27851208/ng-options-with-a-dynamic-expression-is-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!