2013-06-05 14 views
8

czy istnieje sposób, aby transmisja $ propagowała zmienną do $ on podczas fazy inicjalizacji?

<div ng-app='test'> 
    <div ng-controller='testCtrl'> <span>{{testContent}}</span> 
    </div> 
    <div ng-controller="testCtrl2"> 
     <input type='text' ng-change="updateContent()" ng-model="testContent2" /> 
    </div> 
</div> 

 

var app = angular.module('test', []); 
app.factory('sharedContent', function ($rootScope) { 
    var standardContent; 
    var resizeProportion; 
    return { 
     setStandardContent: function (newStandardContent) { 
      standardContent = newStandardContent; 
      $rootScope.$broadcast('updateContent'); 
      console.log('broadcast'); 
     }, 
     getStandardContent: function() { 
      return standardContent; 
     }, 
     setResizeProportion: function (newResizeProportion) { 
      $rootScope.$broadcast('updateResizeProportion'); 
     }, 
    } 
}); 
app.run(function (sharedContent) { 
    sharedContent.setStandardContent('haha'); 
}); 

function testCtrl($scope, sharedContent) { 
    $scope.testContent; 
    $scope.$on('updateContent', function() { 
     console.log('receive'); 
     $scope.testContent = sharedContent.getStandardContent(); 
    }); 
} 

function testCtrl2($scope, sharedContent) { 
    $scope.testContent2 = 'test'; 
    $scope.updateContent = function() { 
     sharedContent.setStandardContent($scope.testContent2); 
    }; 
} 

skrzypacz próbki: http://jsfiddle.net/jiaming/NsVPe/

Rozpiętość wyświetla wartość w zależności od zmian wejściowego, która ze względu na funkcję ng zmiany.

Jednak w fazie inicjalizacji wartość "haha" nie była propagowana do obiektu $ scope.testContent, a zatem nic nie było wyświetlane w pierwszym środowisku wykonawczym. Czy istnieje sposób, aby wartość "haha" pojawiła się w pierwszym uruchomieniu?

Dziękuję.

Odpowiedz

0

Powodem jest to, że ng-change wyzwala po kolejnych zmianach w modelu zidentyfikowanym przez testContent2. Po zainicjowaniu kontrolera przypisywana jest wartość "test". ng-change następnie śledzi kolejne zmiany - początkowe przydział nie kwalifikuje się do tego, tylko kolejne zmiany robią.

http://jsfiddle.net/vZwy4/ - Zaktualizowałem skrzypce dostarczone przez Ciebie. Tutaj widać, że znacznik span jest poprawnie wypełniony danymi.

Zamiast używać funkcji ng-change, należy użyć funkcji zakresu $watch. Dlatego usuń dyrektywę ng-change z pola wprowadzania i usuń metodę updateContent. Zamiast tego, należy go wymienić z następującego kodu, w którym można oglądać zmiany w testContent2 modelu

$scope.$watch('testContent2', function() { 
    if ($scope.testContent2 === undefined || $scope.testContent2 === null) { 
     return; 
    } 

    sharedContent.setStandardContent($scope.testContent2); 

}); 

Teraz można zobaczyć, że słowo „test” (nie mogłem znaleźć nic wspólnego z „haha”) na wyświetlaczu pojawia się gdy ładuje się strona. Kolejne zmiany w danych wejściowych są również aktualizowane w span. Mam nadzieję, że tego właśnie szukałeś.

+0

Witam, jestem rzeczywiście szukają sposobu, aby zainicjować rozpiętość do tekstu „haha” przy pierwszym starcie aplikacji. Myślę, że problem polega na tym, że gdy funkcja sharedContent.setStandardContent ("haha") jest wywoływana w funkcji app.run, kontrolery nie zostały jeszcze utworzone. W związku z tym ciąg "haha" nie jest zapełniany do zakresu w pierwszym uruchomieniu. Czy istnieje inna metoda, którą mógłbym wywołać w celu zapewnienia, że ​​ciąg "haha" jest zapełniany do zakresu w pierwszym środowisku wykonawczym? – jiaming

+0

@jiaming Dlaczego nie ustawisz wartości "haha" w samym TestCtrl2 zamiast ustawić ją na "test"? – callmekatootie

0

To, że nie bierzesz pod uwagę, że faza aplikacji run zostanie wykonana przed inicjalizowanymi kontrolerami. Ponieważ wiadomości rozgłoszeniowe nie są buforowane i są podawane tylko słuchaczom, które nasłuchują w momencie utworzenia wiadomości, wartość haha zostaje utracona.

W twoim przypadku jednak jest to dosyć proste, aby pracować z niewielką zmianą w kontrolerze:

function testCtrl($scope, sharedContent) { 
    updateTestContent(); 
    $scope.$on('updateContent', updateTestContent); 

    function updateTestContent(){ 
    $scope.testContent = sharedContent.getStandardContent(); 
    } 
} 

I rozwidloną swoją JSFiddle tutaj http://jsfiddle.net/y3w5r01d/2/ gdzie można zobaczyć na kiedy każda funkcja konsoli (run i kontrolery) zostaje wykonana.

1

Wystarczy trochę opóźnienia, używając funkcji $timeout. Wystarczy zaktualizować kod w fabryce, aby zaczął działać.

Patrz poniższy kod dla fabryki:

app.factory('sharedContent', function ($rootScope,$timeout) { 
    var standardContent; 
    var resizeProportion; 
    return { 
     setStandardContent: function (newStandardContent) { 
      standardContent = newStandardContent; 
      $timeout(function(){ 
       $rootScope.$broadcast('updateContent'); 
      },0) 
      console.log('broadcast'); 
     }, 
     getStandardContent: function() { 
      return standardContent; 
     }, 
     setResizeProportion: function (newResizeProportion) { 
      $rootScope.$broadcast('updateResizeProportion'); 
     }, 
    } 
}); 
Powiązane problemy