【问题标题】:ng-options with a dynamic expression is not working具有动态表达式的 ng-options 不起作用
【发布时间】:2015-01-09 17:18:34
【问题描述】:

我正在尝试以角度创建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>

This is the example

关于它为什么不起作用的任何线索?

谢谢!

【问题讨论】:

  • 这是一个很好的问题,但我建议在问题本身中包含代码的 relevant 部分。即使链接断开,问题也必须是自我维持的。
  • 感谢@NewDev,已更新!

标签: angularjs angularjs-directive ng-options


【解决方案1】:

这是个好问题。归根结底,当 Angular 正在处理 &lt;select&gt; 时,ng-options 需要有一个值。

1)您可以在“预链接”功能中进行设置:

.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); 添加到您当前的链接函数即可。

【讨论】:

  • 非常感谢@NewDev,$compile(element)(scope) 创造了奇迹!
【解决方案2】:

这是因为你有一个孤立的范围,因此 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;
        }
      }
    }
}]);

【讨论】:

  • 感谢@Yang-li,但这并不能回答我的问题,我正在寻找一种设置 ng-options 的动态方式,而实际上你正在“硬编码”它。
  • 好吧,您的 scope.expression 被硬编码为一个不可变的变量……我为您提供的内容与您之前所拥有的一样动态
  • 是的,但那一行是会改变的。我只是没有添加代码来做到这一点,并且不太清楚。无论如何感谢您花时间回答!
  • 好吧,我编辑了我的答案以包含您想要的内容,尽管它可能不是您的案例中最符合语义的答案,但它肯定对生成很有用
猜你喜欢
  • 1970-01-01
  • 2018-07-14
  • 1970-01-01
  • 1970-01-01
  • 2018-08-29
  • 2023-04-02
  • 2015-08-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多