Директивы AngularJS и модель

Я не уверен, что этот вопрос задавался, но является ли хорошей практикой (недопустимой) возиться с моделью данных из директивы AngularJS?

Например, если в моем контроллере у меня есть какой-то объект, например:

 app.controller("MyCtrl", function () {
      $scope.obj.setOfKnives = ["Ginsu", "Steak"];
 });

И у меня была какая-то кнопка с директивой вроде (написано для краткости):

 <button add-knife>Add a Knife</button/>

В этой директиве add-knife является хорошей практикой (опять же, недопустимой) возиться с этим массивом setOfKnives, например:

 app.directive("addKnife", function () {

      return {
          "restrict": "A",
          "link": function (scope, element, attr) {
                scope.addAKnife = function (theKnife) {
                    scope.obj.setOfKnives.push(theKnife);
                };

                element.on("click", function () {
                    scope.addAKnife("Serrated");
                });
          }
      };
 });

(Я считаю, что было бы лучше сделать эту директиву директивой элемента с шаблоном...)
Так это хорошая практика? Или я должен использовать директиву для добавления объектов DOM на страницу, а некоторая функция контроллера позаботится о добавлении и удалении элементов из массива setOfKnives на основе DOM?


person gonzofish    schedule 26.09.2013    source источник
comment
Я бы добавлял/удалял элементы в контроллере.   -  person kubuntu    schedule 26.09.2013


Ответы (2)


Управление моделью внутри директивы — это путь. Следует избегать прямых манипуляций с DOM.

Чтобы сделать директиву более модульной, вы можете передать массив как атрибут директивы и создать изолированную область, которая ограничивает то, что будет совместно использоваться контроллером этой директивы.

<button add-knife knives="setOfKnives" >Add a Knife</button/>

В директиве

app.directive("addKnife", function () {

      return {
          "restrict": "A",
           scope:{ knives:'='},
           "link": function (scope, element, attr) {
                 scope.addAKnife = function (theKnife) {
                    scope.knives.push(theKnife);
                };

          }
      };
 });

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

person Chandermani    schedule 26.09.2013
comment
но скажем, у меня есть некоторый ng-repeat, который отображает ножи по мере их добавления... если бы я сделал ‹span ng-repeat=knife in knifes...›, он привязался бы, как я сделал scope.knives.push? - person gonzofish; 26.09.2013
comment
Да, пока директива и контроллер используют одни и те же ссылки на ножи, это также будет обновлять и обновлять DOM пользовательского интерфейса. Я думаю, что если вы создаете директиву только для того, чтобы добавить нож и обновить DOM на основе добавления, вам вообще не нужна директива. - person Chandermani; 26.09.2013
comment
Во-первых, спасибо @Changermani за помощь. Проблема в том, что я имею дело с несколькими областями и пытаюсь повлиять на модель данных всех из них с помощью директивы. - person gonzofish; 26.09.2013

в любом случае, у вас будет доступ к внутреннему состоянию DOM, и вы можете изменить модель внутри директивы, но директивы представляют собой настраиваемые элементы управления, которые предназначены для использования на различных страницах, поэтому в идеале они должны вести себя как другие элементы управления, а пользовательская логика должна быть делегирована Сервисы/контроллеры, чтобы директиву можно было повторно использовать без изменений

person TalentTuner    schedule 26.09.2013