javascript - Izolarea domeniului "=" legătură și notație punctată AngularJS


Cum creezi o legătură bidirecțională cu o proprietate încorporată într-un scope izolat folosind notația punctată. Am crezut că 'myObject.data': "=data" ar funcționa, dar nu funcționează. Nu vreau să conectez totul din obiectul myObject. Știu că aș putea folosi un fel de watch, dar 'myObject.data' pare mai curat.

.directive("myDirective", [function() {
    return {
        restrict: "E",
        scope: {
            'myObject.data': "=data"
        },
        link: function (scope, element, attrs) {

            scope.myObject = {
                 data: "myValue"
            };
        }
     };
 }])

Răspuns #1

Scopurile izolate sunt în general utile doar cu șabloane, nu ar trebui să fie folosite ca o modalitate de a declara cum doriți ca atributele directivei să fie interpretate. Acest lucru se datorează faptului că majoritatea directivelor care nu au un șablon au de obicei nevoie de semantica fie a unui scop copil, fie a scopului direct al mediului lor.

În cazul tău, probabil nici măcar nu ai nevoie de un $watch, deoarece referințele obiectelor sunt cele care permit legarea bidirecțională a datelor, dar fără codul tău complet nu pot fi sigur.

În cazul în care doriți să cunoașteți traducerile pentru o semantică cu scop izolat către una normală:

@name -> attrs.name
=name -> $scope.$eval(attrs.name);
&name -> function() { return $scope.$eval(attrs.name); } 

EDITARE 2:

După comentariul tău, mi-a venit în minte acest plunker. Pentru a păstra legarea bidirecțională a datelor, trebuie să folosești un „.” în declarația ng-model. Acest lucru se datorează faptului că legarea bidirecțională a datelor nu funcționează pentru tipurile de valori, deoarece acestea sunt imuabile. Nu poți schimba valoarea de 100, de exemplu. Trebuie să transmiți un obiect de tip referință și să atașezi valorile pe care le schimbă acolo. Dorința ta de a specifica calea completă către valoare în definiția scope-ului izolat nu este posibilă pe baza principiilor care fac posibilă legarea bidirecțională a datelor.

Javascript :

angular.module('plunker', [])

.directive('twoWay', function() {
  return {
    restrict: 'E',
    template: '<div><input ng-model="thing.name" type="text" /></div>',
    scope: {
      thing: "="
    }, 
    link: function(scope, element, attrs) {
    }
  };
})

.controller('MainCtrl', function($scope) {
  $scope.data = {
    name: "World"
  };
});

HTML :

  <body ng-controller="MainCtrl">
    <p>Hello {{data.name}}!</p>
    <two-way thing="data"></two-way>
  </body>

Răspunsul #2

Ceea ce folosesc în aceste cazuri este următorul:

.directive("myDirective", [function() {
    return {
        restrict: "E",
        scope: {
            data: "="
        },
        controller: function($scope){
           $scope.dot = $scope //<--- here is the trick
        } 
     };
 }])

Atunci poți întotdeauna să schimbi data în sfera directivei dintr-o sferă moștenită prin dot.data='whatever' fără a seta observatori.

Nu este foarte elegant, dar funcționează foarte bine în cazurile în care nu folosești sintaxa controller as și nu vrei un coșmar cu $parent.