2017-05-31 2 views
0

Also ist mein Ziel, ng-repeat über eine Reihe von Aktivitäten und zeigen Sie eine bestimmte Direktive basierend auf dem Aktivitätstyp. Gerade jetzt teste ich die Idee, um zu sehen, ob es lebensfähig ist. Ich kann eine Anweisung dynamisch anzeigen, aber der Schlüssel ist, dass ich eine bidirektionale Bindung zwischen den Aktivitäten in der main.js und der angezeigten Anweisung haben möchte.Zwei-Wege-Bindung in der dynamischen Winkel-Direktive

main.html

<div ng-controller="mainCntrl"> 
    <div>Activity: { <div>isIncluded: {{activities[0].isIncluded}}</div> }</div> 
    <dynamic-directive type="{{activities[0].type}}" attributes="instance='activities[0]'"></dynamic-directive> 
</div> 

main.js

define(['angularAMD', 'dynamicDirective', 'activity1'], 
    function (angularAMD) { 
     'use strict'; 

     var app = angular.module('mainModule', []); 

     app.controller('mainCntrl', ['$rootScope', '$scope', 
      function ($rootScope, $scope) { 
       $scope.activities = [{ 
        type: "activity1", 
        isIncluded: true 
       }]; 
      }]); 
    }); 

dynamicDirective.js

define('dynamicDirectiveModule', ['angularAMD'], function (angularAMD) { 
    'use strict'; 
    var app = angular.module('dynamicDirectiveModule', []); 

    app.directive('dynamicDirective', ['$compile', 
     function ($compile) { 
      return { 
       restrict: 'E', 
       scope: { 
        type: '@', 
        attributes: '@' 
       }, 
       link: function (scope, element) { 
        var generatedDirective = '<' + scope.type + ' ' + scope.attributes + '></' + scope.type + '>'; 
        element.append($compile(generatedDirective)(scope)); 
       } 
      }; 
     } 
    ]); 
}); 

activity1.js

define('activity1Module', ['angularAMD'], function (angularAMD) { 
    'use strict'; 
    var app = angular.module('activity1Module', []); 

    app.controller('activity1Cntrl', ['$scope', 
     function ($scope) { 
      console.log("$scope.instance: " + $scope.instance); 
      $scope.thisInstance = $scope.instance || {}; 
     } 
    ]); 

    app.directive('activity1', [ 
     function() { 
      return { 
       restrict: 'E', 
       templateUrl: 'processes/templates/Activity1', 
       controller: 'activity1Cntrl', 
       scope: { 
        instance: '=' 
       } 
      }; 
     } 
    ]); 
}); 

activity1.html

<div> 
    <div>ISINCLUDED: {{thisInstance.isIncluded}}</div> 
    <button ng-model="thisInstance.isIncluded" value="true">Yes</button> 
    <button ng-model="thisInstance.isIncluded" value="false">No</button> 
</div> 

Mit der Art und Weise es jetzt eingerichtet ist, die console.log Ausgänge, die $ scope.instance ist nicht definiert. Also ist $ scope.thisInstance.isInclude standardmäßig auf false gesetzt. Wenn ich in der main.html attributes="instance='{{activities[0]}}'" setze, wird $ scope.thisInstance.isIncluded korrekt auf true gesetzt, aber ich habe keine bidirektionale Bindung, da anstelle von activities [0] als im Wesentlichen ein Zeiger übergeben wird Wert, {Typ: "activity1", isIncluded: true}. Wie kann ich die beidseitige Bindung zum Funktionieren bringen? Ist es möglich? Gibt es einen besseren Weg, dies zu tun?

+0

Haben Sie versucht, ng-include? May not that fancy, but much simplier –

+0

Ich habe mir das angeschaut, aber von dem, was ich sagen konnte, kompiliert ng-include nur den html. Stattdessen brauche ich eine echte Direktive, obwohl mein Beispiel oben nur zwei Schaltflächen hat. Ich beabsichtige mehr Funktionalität wie das Speichern der Aktivitäten, die ich wiederverwenden möchte. – ScubaSteve

+0

Umfang: { Typ: '=', Attribute: '=' } Ihren Umfang schreiben, wie der –

Antwort

0

Meine aktuelle Problemumgehung dafür ist, ng-switch zu verwenden und dynamicDirective.js zu umgehen.

main.html

<div ng-switch="activity.type" ng-repeat="activity in activities"> 
    <activity1 ng-switch-when="activity1" instance="activity"></activity1> 
    <activity2 ng-switch-when="activity2" instance="activity"></activity2> 
</div> 

Dies ist nicht optimal, da es schnell hässlich bekommen konnte. Ich werde das nicht als die Antwort markieren, da es nur ein Workaround ist.

Verwandte Themen