2013-10-17 15 views
11

Bazı geri bildirimleri, yalnızca direktifin (ya da yalnızca bazılarının) tüm özniteliklerini (yalıtılmış kapsam olmadan) değerlendirdikten sonra bir kez gerçekleştirebilirsiniz. Nitelikler, yapılandırmayı direktiflere aktarmak için gerçekten harikadır. Mesele, her bir özelliği ayrı ayrı gözlemleyebilmeniz ve birkaç kez geri arama yapabilmenizdir.

Örnekte, iki özniteliği gözlemleyen izole bir kapsam bulunmayan bir yönergeye sahibiz: ad ve soyad. herhangi değişiklikten sonra action geri arama ateşlenir:

html

<button ng-click="name='John';surname='Brown'">Change all params</button> 
<div person name="{{name}}" surname="{{surname}}"></div> 

js

angular.module('app', []). 

directive('person', function() { 
    return { 
    restrict: 'A', 
    link: function($scope, $elem, $attrs) { 
     var action = function() { 
      $elem.append('name: ' + $attrs.name + '<br/> surname: ' + $attrs.surname+'<br/><br/>'); 
     } 
     $attrs.$observe('name', action); 
     $attrs.$observe('surname', action); 
    } 
} 
}); 

Plunker here.

Yani etkisi o tek bir tıklama esnasında Soyadınız değiştirdikten sonra, action geri arama iki kez ateşlenir edilir:

name: 
surname: Brown 

name: John 
surname: Brown 

Yani soru şu: action adı soyadı değerleri hem değiştirilen ile sadece bir kez ateş edilebilir?

cevap

11

Belirli bir model yerine özel bir işlevi değerlendirmek için $watch kullanabilirsiniz.

tüm $digest döngüleri üzerinde çalışan ve olacaktır

$scope.$watch(function() { 
    return [$attrs.name, $attrs.surname]; 
}, action, true); 

yani $watch (veya işlevin dönüş değeri yapılandırmak istediğiniz ancak) eski değeri eşleşmiyor, geri arama dönüş dizisi algılarsa $watch argümanı tetiklenir. Geri dönüş değeri olarak bir nesneyi kullanırsanız, $watch için son bağımsız değişken için true değerini bırakın, böylece $watch derin bir karşılaştırma yapar.

+0

Çok teşekkür ederim: Burada

uygulaması ile orijinal plunkr bir çatal olduğunu! – iamtankist

0

Alt çizgi (veya çizgi izleri) once işlevine sahiptir. Fonksiyonunuzu once içine sardığınızda, fonksiyonunuzun sadece bir kez çağrıldığından emin olabilirsiniz.

angular.module('app', []). 

directive('person', function() { 
    return { 
    restrict: 'A', 
    link: function($scope, $elem, $attrs) { 
     var action = function() { 
      $elem.append('name: ' + $attrs.name + '<br/> surname: ' + $attrs.surname+'<br/><br/>'); 
     } 
     var once = _.once(action); 
     $attrs.$observe('name', once); 
     $attrs.$observe('surname', once); 
    } 
} 
}); 
+2

Maalesef '_.once' yalnızca bir kez geri arama yapacaktır ancak sadece ilk özellik değiştirilmiştir. Benim amacım, tek bir "$ digest" fazı sırasında yapılan tüm değişikliklerden sonra geri çekilmenin yapılması gerektiğidir. – kseb

0

Yani, bir çağrı yığını sırasında özelliklerin birkaç değişiklik bekleyebilir observeAll yöntemin, benim kendi uygulanması ile sona erdi ettik. Ancak performans konusunda emin değilim.

@cmw özümünün daha basit olduğu görülüyor; ancak, nesne eşitliği birçok kez değerlendirildiğinde, performans çok sayıda parametre ve birden fazla $ digest fazı çalışmasından zarar görebilir. Ancak cevabını kabul etmeye karar verdim.

sen benim yaklaşımı bulabilirsiniz:

angular.module('utils.observeAll', []). 

factory('observeAll', ['$rootScope', function($rootScope) { 
    return function($attrs, callback) { 
     var o = {}, 
      callQueued = false, 
      args = arguments, 

      observe = function(attr) { 
       $attrs.$observe(attr, function(value) { 
        o[attr] = value; 
        if (!callQueued) { 
         callQueued = true; 
         $rootScope.$evalAsync(function() { 
          var argArr = []; 
          for(var i = 2, max = args.length; i < max; i++) { 
           var attr = args[i]; 
           argArr.push(o[attr]); 
          } 
          callback.apply(null, argArr); 
          callQueued = false; 
         }); 
        } 
       }); 
      }; 

     for(var i = 2, max = args.length; i < max; i++) { 
      var attr = args[i]; 
      if ($attrs.$attr[attr]) 
       observe(attr); 
     } 
    }; 
}]); 

Ve siz yönergede kullanabilirsiniz:

angular.module('app', ['utils.observeAll']). 

directive('person', ['observeAll', function(observeAll) { 
    return { 
    restrict: 'A', 
    link: function($scope, $elem, $attrs) { 
     var action = function() { 
      $elem.append('name: ' + $attrs.name + '<br/> surname: ' + $attrs.surname+'<br/><br/>'); 
     } 
     observeAll($attrs, action, 'name', 'surname'); 
    } 
} 
}]); 

Plunker

0

here kullandığımı vardı aynı sorunu çözüldü Başka bir yaklaşım, farklı fikirler aradığım halde. Cmw'nin önerileri işe yarıyorken, performansını benimki ile karşılaştırdım ve $ watch yönteminin çok fazla çağrıldığını gördüm, bu yüzden işleri gerçekleştirdiğim şekilde tutmaya karar verdim.

Her iki değişken için de çağrıları gözlemleme ekledim. Bir geri çağırma çağrısına onları izlemek ve sınırlamak istedim.

var debounceUpdate = _.debounce(function() { 
    setMinAndMaxValue(attrs['minFieldName'], attrs['maxFieldName']); 
}, 100); 

attrs.$observe('minFieldName', function() { 
    debounceUpdate(); 
}); 

attrs.$observe('maxFieldName', function() { 
    debounceUpdate(); 
}); 
0

bu sorunu çözmek için sunulan çeşitli yolları vardır: onlar bu yana hem hem $ gözlemlemek yöntemler kısa bir gecikmeden sonra işletilirse aynı işlev çağrısını tetikleyen, çok az zaman farkı değiştirilir. Çözülme çözümünü çok beğendim. Ancak, bu problem için benim çözümüm. Bu, tüm nitelikleri tek bir özellikte birleştirir ve ilgilendiğiniz özelliklerin bir JSON temsilini oluşturur. Şimdi, yalnızca bir özelliği gözlemlemeniz ve iyi bir perfete sahip olmanız yeterlidir! linkhttp://plnkr.co/edit/un3iPL2dfmSn1QJ4zWjQ

İlgili konular