javascript
  • angularjs
  • angularjs-directive
  • angular-ui
  • ui-select2
  • 2013-09-10 1 views 0 likes 
    0

    У меня есть директива, которая берет в коллекции и выстраивает выпадающий список.ui-select2 inside директива не обновляет модель контроллера

    .directive("lookupdropdown", function() { 
        return { 
         restrict: 'E', 
         scope: { 
          collectionset: '=', 
          collectionchoice: '=' 
         }, 
         replace: true, 
         template: '<select class="input-large" ui-select2 ng-model="collectionchoice" data-placeholder="">' + 
            ' <option ng-repeat="collection in repeatedCollection" value="{{collection.id}}">{{collection.description}}</option>' + 
            '</select>', 
         controller: ["$scope", function ($scope) { 
          $scope.repeatedCollection = new Array(); //declare our ng-repeat for the template 
          $scope.$watch('collectionset', function() { 
           if ($scope.collectionset.length > 0) { 
            angular.forEach($scope.collectionset, function (value, key) { //need to 'copy' these objects to our repeated collection array so we can template it out 
             $scope.repeatedCollection.push({ id: value[Object.keys(value)[0]], description: value[Object.keys(value)[1]] }); 
            }); 
           } 
          }); 
    
          $scope.$watch('collectionchoice', function (newValue, oldValue) { 
           debugger; 
           $scope.collectionchoice; 
          }); 
         } ] 
        } 
    }); 
    

    Это прекрасно работает. Это создает проблему без проблем. Когда я изменяю выпадающее значение, вызывается вторая функция часов, и я вижу, что она устанавливает значение выбора коллекции для того, что я хочу. Однако набор, который я ввел в директиву, не привязан к новому выбору.

    <lookupDropdown collectionset="SecurityLevels" collectionchoice="AddedSecurityLevel"></lookupDropdown> 
    

    Это разметка HTML.

    Это JavaScript:

    $scope.SecurityLevels = new Array(); 
    $scope.GetSecurityLevelData = function() { 
        genericResource.setupResource('/SecurityLevel/:action/:id', { action: "@action", id: "@id" }); 
        genericResource.getResourecsList({ action: "GetAllSecurityLevels" }).then(function (data) { 
         $scope.AddedSecurityLevel = data[0].SCRTY_LVL_CD; 
         $scope.SecurityLevels = data; 
         //have to get security levels first, then we can manipulate the rest of the page 
         genericResource.setupResource('/UserRole/:action/:id', { action: "@action", id: "@id" }); 
         $scope.GetUserRoles(1, ""); 
        }); 
    } 
    $scope.GetSecurityLevelData(); 
    

    Тогда, когда я иду, чтобы опубликовать свою новую роль пользователя, я устанавливаю поле роли пользователя, как это:

    NewUserRole.SCRTY_LVL_CD = $scope.AddedSecurityLevel; 
    

    , но это по-прежнему быть первым item EVEN, хотя я обновил раскрывающееся меню, которое, согласно функции часов, изменилось на правильное значение. Что мне здесь не хватает?

    ответ

    0

    Проблема заключалась в том, что моя директива была переведена в другую директиву. Создание области im, проходящей в дочернем элементе директивы, в которой она была. Итак, что-то вроде $ parent -> $ child -> $ child. Это, конечно, вносит изменения в третий слой и второй слой. Но первый слой понятия не имел, что происходит. Это зафиксировало его:

    <lookupDropdown collectionset="SecurityLevels" collectionchoice="$parent.AddedSecurityLevel"></lookupDropdown> 
    
    1

    Вы столкнулись с этой проблемой из-за прототипичную природу наследования в JavaScript. Позвольте мне попытаться объяснить. Все является объектом в Javascript, и как только вы создаете объект, он наследует все Object.Prototype (ы), который в конечном итоге приводит к конечному объекту, то есть объекту. Вот почему мы можем .toString() каждый объект в javascript (четные функции), потому что все они унаследованы от Object.

    Этот конкретный вопрос о директивах возникает из-за непонимания $ scope в Angular JS. $ scope - не модель, а контейнер для моделей. Смотрите ниже для правильного и неправильного способа определения моделей на $ объеме:

    ... 
    $scope.Username = "[email protected]"; //Incorrect approach 
    $scope.Password = "thisisapassword";//Incorrect approach 
    ... 
    $scope.Credentials = { 
        Username: "[email protected]", //Correct approach 
        Password: "thisisapassword" //Correct approach 
    } 
    ... 
    

    Два заявления делают большую разницу. Когда ваша директива обновляет свою область действия (изолированная область действия директивы), она фактически полностью избавляет ссылку от нового значения, а не обновляет фактическую ссылку на родительскую область, поэтому она отключила область действия директивы и контроллера.

    Ваш подход заключается в следующем:

    <lookupDropdown collectionset="SecurityLevels" collectionchoice="$parent.AddedSecurityLevel"></lookupDropdown> 
    

    Проблема с этим подходом является то, что, хотя он работает, но не рекомендуемое решение, и вот почему. Что делать, если ваша директива находится внутри другой директивы с другой изолированной областью между областью действия вашей директивы и фактическим контроллером, в этом случае вам нужно будет сделать $parent.$parent.AddedSecurityLevel, и это может продолжаться вечно. Поэтому НЕ рекомендуемое решение.

    Вывод:

    Всегда убедитесь, что есть объект, который определяет модель от объема и всякий раз, когда вы использовать изолят областей или использовать директивы нг, которые используют изолят прицелы т.е.ng-model просто посмотрите, есть ли точка (.) Где-то, если она отсутствует, вы, вероятно, делаете что-то неправильно.

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

    • Нет связанных вопросов^_^