AngularJS: область ngRepeat не работает в пользовательской директиве с изолированной областью и ngTransclude

Я создал пользовательскую директиву («мастер») на основе плагина JQuery Steps. Но я сталкиваюсь с проблемами при использовании ngRepeat внутри моей директивы. Директива использует ngTransclude, поэтому я могу предоставить содержимое шагов внутри разметки страницы.

Я далеко не эксперт по Angular, но я могу найти, что это ошибка / freakacident в Angular, где ngRepeat используется внутри директивы с изолированной областью действия и включением. Как упоминалось здесь https://github.com/angular/angular.js/issues/7874 но я не могу заставить ни одно из предложений работать :\

Директива выглядит так:

Directives.wizard = ['$compile', function ($compile) {
return {
    restrict: 'E',
    scope: {
        cancel: '&',
        finish: '&',
        stepChanged: '&'
    },
    template: '<div class="wizard" data-ng-transclude></div>',
    replace: true,
    transclude: true,
    link: function ($scope, element, attrs, ctrl) {
        // directive has to be wrapped in order to ngModel on sections to work with transclude: true
        element.wrapInner('<div class="steps-wrapper">');

        var opts = {
            headerTag: "h3",
            bodyTag: "section",
            transitionEffect: "slideLeft",
            onCanceled: function (event, currentIndex) {
                $scope.cancel();
            },
            onFinished: function (event, currentIndex) {
                $scope.finish();
            },
            onStepChanged: function (event, currentIndex) {
                $scope.stepChanged();
            }
        };

        var stepsEl = element.children('.steps-wrapper').steps(opts);

        // wrap 'n compile..
        $compile(stepsEl)($scope);
    }
};}];

разметка

<wizard>
<h3>Title</h3>
<section>
    <p><DG:TextControl runat="server" Key="MineSuccesHistorier.Step1"/></p>
    <input data-ng-model="$parent.newData.Title"></input> <!-- outputs array just fine -->

    <!-- test stuff here -->
    <!-- 1. regular ng-repeat - doesnt work (also tried with $parent.$parent which Batarang says is the correct path -->
    <ul>
        <li data-ng-repeat="item in $parent.newData.Competences">{{item.Title}}</li>
    </ul>

    <!-- 2. try with ng-init - doesnt work -->
    <ul data-ng-init="comp = $parent.newData.Competences">
        <li data-ng-repeat="item in comp">{{item.Title}}</li>
    </ul>
</section>

<h3>Tab</h3>
<section>
    <!-- next wizard tab here -->
</section>                

How data is set in controller

$scope.newData = {
"Competences": [
    {
        "IsSelected": true,
        "Title": "Hest"
    },
    {
        "IsSelected": false,
        "Title": "Kat"
    },
    {
        "IsSelected": true,
        "Title": "Ko"
    },
    {
        "IsSelected": false,
        "Title": "Ged"
    }
],
"Id": "905c1285-d58b-4f65-8df5-52986c70a820",
"Situation": null,
"Title": null}

любые идеи высоко ценятся, заранее спасибо!

ОБНОВЛЕНИЕ 25/3: plnkr добавлен здесь http://plnkr.co/edit/kNl4UEoUa7zU4CgWaGSa?p=preview Когда я добавляю изолированную область в директиву, повторители перестают работать. Если я оставлю изолированную область, кажется, что ngRepeats компилируются несколько раз.

ОБНОВЛЕНИЕ 2 25/3: Добавлен новый plunkr с предложением компиляции Vinays - теперь ng-repeat компилируется только один раз. Но двусторонняя привязка с ngModel в области контроллера не работает http://plnkr.co/edit/TR3XxvV4IYI66h4pY5hx?p=preview


person morteng    schedule 18.03.2015    source источник
comment
У вас есть plnkr/скрипка для этого?   -  person Vinay K    schedule 18.03.2015
comment
Привет, Винай, да, я только что добавил plunkr :) Когда я добавляю изолированную область в директиве, повторители перестают работать. Если я оставлю изолированную область, кажется, что ngRepeats компилируются несколько раз.   -  person morteng    schedule 25.03.2015
comment
Пожалуйста, напишите версию вашего кода, которая изолирует эту проблему. Я просматривал ваш код последние пару минут и до сих пор не знаю, каков предполагаемый результат и в чем проблема.   -  person Sergiu Paraschiv    schedule 25.03.2015
comment
Также в моем браузере все три слайда изначально перекрываются. Это проблема?   -  person Sergiu Paraschiv    schedule 25.03.2015


Ответы (1)


Содержимое повторяется, потому что ng-repeat скомпилирует содержимое один раз, а $compile скомпилирует его еще раз.

Директива

app.directive('wizard', function($timeout, $compile) {   
  return {
    restrict: 'E', 
    replace: true,
    template: '<div class="mywizard"></div>', 
    compile: function (tEl) {
      return function(scope, element, attrs) {
        var stepsEl;

        element.wrapInner('<div class="steps-wrapper">');
        element.children('.steps-wrapper').append(tEl.context.innerHTML);
        var content = $compile(element.contents())(scope);
        $timeout(function () {
          element.children('.steps-wrapper').steps(opts);
        })
      }
    }
  };
});

Рабочий план

person Vinay K    schedule 25.03.2015
comment
Привет, Винай, спасибо за помощь - приятно видеть, что повторитель не компилируется несколько раз. Я знал, в чем проблема, но не знал, как ее решить. Единственное, чего мне сейчас не хватает, так это двусторонней привязки, поэтому я могу обновить свою модель данных в области контроллера и использовать изолированную область. Я сделал планкр здесь plnkr.co/edit/TR3XxvV4IYI66h4pY5hx?p=preview это показывает проблему. Фамилия печатается с {{lastname}}, но поле ввода с ng-model=firstname не отображается и не обновляется. Любые идеи? - person morteng; 25.03.2015
comment
Когда вы указываете isolateScope, он разрывает цепочку из области действия контроллера. Вместо isolateScope попробуйте scope:true. Обновлен plnkr: plnkr.co/edit/lHQyXyN0yAzIob67X21X?p=preview - person Vinay K; 26.03.2015