2015-01-08 4 views
0

Я пытаюсь создать directive в угловом, чтобы заменить обычный выпадающий список. Мне нужно установить динамическое выражение в ng-options, но, похоже, оно не работает внутри директивы.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

Любой ключ о том, почему он не работает?

Спасибо!

+0

Это хороший вопрос, но я предлагаю включить ** соответствующие ** части кода в самом вопросе. Вопрос должен быть самоподдерживающимся, даже если связь нарушена. –

+0

Спасибо @NewDev, обновлено! – Mustela

ответ

1

Это хороший вопрос. В конце дня ng-options должен иметь значение, когда <select> обрабатывается угловым.

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), если ваше выражение действительно должно быть изменяемым и modifyable (кажется странным случае и, вероятно, следует адрес с более подходящим ViewModel), то вам нужно, чтобы заставить повторную компиляцию :

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

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

Btw, просто добавив $compile(element)(scope); к вашей текущей функции связи, это поможет.

+0

Спасибо большое @NewDev, '$ compile (element) (scope)' did магия! – Mustela

0

Это потому, что у вас есть изолированный объем и, таким образом, ngOptions не подается в этом значении правильно

Изменения ур шаблона для

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

Edit: если вы действительно хотите передать узел, который нужно делайте это в функции компиляции, потому что это когда директива 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; 
     } 
     } 
    } 
}]); 
+0

Спасибо @ Yang-li, но это не отвечает на мой вопрос. Я ищу динамический способ настройки ng-опций, и там вы на самом деле «hardcoding». – Mustela

+0

Хорошо, что ваше scope.expression жестко закодировано в переменную, которая не изменена ... Что я вам предоставил, не менее динамично, чем то, что было у вас до –

+0

Да, но эта строка будет меняться. Я просто не добавлял код, чтобы сделать это, и было не так ясно. В любом случае спасибо, что нашли время ответить! – Mustela

Смежные вопросы