2016-04-11 2 views
1

Я пытаюсь создать N число Выберите Элемент управления динамически управляется директивой на основе массива, который передается из атрибута (где N - длина массива).AngularJS не анализирует динамически загруженные данные из директивы

Структура объекта массива, как например:

selectDescription = { 
    array: arrayObject, //ng-options, a string as 'item as item.name for item in selectArray[0]' 
    change: methodName, //ng-change, actionname 
    level: levelNumber //level number 
} 

Таким образом, число отборного управления внутри диапазон тег зависит от количества selectDescription(s), что я получаю от этого атрибута.

Первый элемент управления успешно завершен. Последующие элементы управления выбора должны были отображаться при выборе опции от предыдущий отображаемый выбор элементов управления. Но этого не происходит в моем случае. Хотя я успешно добавляю угловые элементы в текущем inputEl (по выбору опции), он не отображается в пользовательском интерфейсе. Наверное, мне не хватает чего-то очень важного.

Об изменении selectDescriptions, Перевернутый атрибут установлен, с помощью которого я могу назвать scope.$editable.render() от линии, которая, в свою очередь, запускает функцию визуализации повторно добавить в конец элементы после очистки предыдущего HTML внутри span.

Мой код:

app.directive('editableLocation', function(editableDirectiveFactory) { 
    var createElement = function(el, index){ 
     var newElement = angular.element("<select/>"); 
     newElement.attr('ng-model','$data'+index); 
     newElement.attr('ng-options',el.array); 
     newElement.attr('ng-change',el.change.substring(0, el.change.length - 1)+", $data"+index+")"); 
     return newElement; 
    } 

var descriptions = [] ; 
var dir = editableDirectiveFactory({ 
    directiveName: 'editableLocation', 
    inputTpl: '<span></span>', 
    render: function() { 
    this.parent.render.call(this); 
    this.inputEl.html(""); 
    for(var i = 0 ; i < descriptions.length ; i ++){ 
     this.inputEl.append(createElement(descriptions[i], i)); 
    } 
    } 
}); 
var linkOrg = dir.link; 

dir.link = function(scope, el, attrs, ctrl) { 
    console.log(el); 
    descriptions = scope.$eval(attrs.description); 
    scope.$watch('flipped',function(newValue,oldValue){ 
     if(newValue != 0){ 
      scope.$editable.render(); 
     } 
    }); 
    return linkOrg(scope, el, attrs, ctrl); 
}; 

return dir; 
}); 

ответ

1

Так как вы добавляете динамическое содержимое HTML в link функции угловой директивы, Угловой не автоматическая компиляция/разобрать его. Вам нужно сделать это вручную, используя директиву $compile. Таким образом, после того, как вы приложили все HTML, выполните следующие действия (инъекционные $compile в коде)

$compile(element.contents())(scope); 

Где element ваш любой родительский элемент, где вы создаете динамический HTML и scope является сфера применения директивы или любой другой сфера который вы хотите, чтобы он был привязан к динамическому HTML.

+0

Я сделал, как вы сказали. Хотя он показывает два элемента управления внутри this.inputEl.contents(), он по-прежнему не отображает одинаковое количество элементов управления в пользовательском интерфейсе. –

+0

Возможно, это проблема с вашим кодом. Можете ли вы предоставить plunkr или скрипку? –

+0

Здесь вы идете https://plnkr.co/edit/lX7aBnJz9b2D9p35Hke6?p=preview –

0

Глядя на xeditable.js Я обнаружил, что xeditable делает пользовательский интерфейс, вызывая метод show, определенный в его editableController.

Оно определяется как:

self.show = function() { 
    self.setLocalValue(); 
    self.render(); //calls 'render' function of 'editableDirectiveFactory'; that' where my custom UI lies 
    $element.after(self.editorEl); //attaches newelement(especially whole <form/> element) 
    $compile(self.editorEl)($scope); //renders whole UI(and also the newly attached one) 
    self.addListeners(); 
    $element.addClass('editable-hide'); 
    return self.onshow(); 
}; 

Так что я чувствовал, есть, мне нужно вызвать этот метод show из моей link функции, которая принимает controller.

Это то, что я сделал:

dir.link = function (scope, el, attrs, ctrl) { 
    $element = el; 
    scope.$watch(attrs.flipped, function (newValue, oldValue) { 
     //re-render element if flipped is changed; denoting description of select controls have been altered 
     if (newValue != 0) { 
      ctrl[0].show(); //this will call render function and also $compile({{content/html/element}})(scope) 
     } 
    }); 
    return linkOrg(scope, el, attrs, ctrl); 
}; 

А также вам нужно скрыть предыдущий <form/> элемент (который содержит предыдущий вынесенное UI), так что получить отображается только один формы.

Это как я скрывал, что предыдущий <form/> элемент в render' function of editableDirectiveFactory`:

var prevForm = $element[0].nextElementSibling; //hide previous form element which would already contain previous select 
if (prevForm) 
    prevForm.classList.add('editable-hide'); 

Это решило мою проблему, по крайней мере :)

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