2013-08-02 6 views
5

Hier ist die jsfiddle beispielhaft für meine Situation.Empfangen von Broadcasts und Aufruf von Controller-Funktionen aus isolierten Bereich/Direktive in AngularJS?

Zuallererst, ist dies der richtige Weg, Richtlinien mit den empfangenen Dimensionen zu erstellen? Dann sollte jede Direktive von den anderen isoliert werden. Daher verwende ich scope: {}.

Das Problem Funktionen aufruft, die .. in der Steuerung sind, und es scheint nicht die Sendung erhält entweder ..

Ich bin sicher, dass dies ein triviales Problem ist .. Ich bin neu in Angular :)

ich habe eine Seite, in der ich eine Reihe von Komponenten mit ng-repeat laden:

<div ng-app="test"> 
    <div ng-controller="containerCtrl"> 
     <component ng-repeat='c in components' id="c.id" my-width="{{c.width}}" my-height="{{c.height}}"> 
    </div> 
</div> 

der Controller:

controller('containerCtrl', function ($scope) { 
    $scope.components = [{ id: "c1", width: 100, height: 100 }, 
         { id: "c2", width: 200, height: 100 }, 
         { id: "c3", width: 300, height: 100 }]; 

    //in the actual controller I am using a socket provider and doing 
    //socket.forward([ 
    //  'initPage', 
    //  'refreshPage' 
    // ], $scope); 
    //simulating it with a simple broadcast here.. 
    $scope.$broadcast("onSomething", ""); 

    $scope.doSomething = function (data) { 
     alert("doing something"); 
    }; 
}). 

und die Richtlinie:

directive('component', function() { 
     var linkFn = function(scope, element, attrs) { 
      $(element). 
       resizable({ 
        stop: function(event, ui) { 
         scope.emitSomething(attrs.id, ui.position); 
        } 
       }); 

      scope.$on('onSomething', function(res) { 
       alert("onSomething!"); 
      }); 
     }; 

     return { 
      restrict: 'E', 
      template: '<div class="ui-widget-content" style="width: {{width}}px; height: {{height}}px;"></div>', 
      replace: true, 
      scope: { 
       width:'@myWidth', 
       height:'@myHeight' 
      }, 
      link : linkFn 
     }; 
    }); 

Antwort

16

Die Steuerung wird ausgeführt, bevor die Link-Funktion, so dass Ihre Sendung zu geschickt bald wird. Sie können dies mit $timeout verzögern:

$timeout(function() { 
    $scope.$broadcast("onSomething", ""); 
}); 

Um eine Controller-Methode aus einer Richtlinie mit einem Isolat Umfang aufrufen, müssen Sie die Methode als Argument angeben:

<component ng-repeat='c in components' id="c.id" my-width="{{c.width}}" 
my-height="{{c.height}}" callbk="doSomething(data)"> 

und Sie müssen die verwenden & Syntax in der Richtlinie:

scope: { 
    width: '@myWidth', 
    height: '@myHeight', 
    emitSomething: '&callbk' 
}, 

um Parameter zu diesem Rückruf/Controller-Funktion übergeben, müssen Sie die richtige Syntax verwenden: 012.313.. In der Geige, habe ich nur ein Argument, und übergeben die beiden Parameter in einem Array statt:

$(element).resizable({ 
    stop: function (event, ui) { 
     scope.emitSomething({data: ["id", "position"]}); 
    } 
}); 

fiddle

+0

Perfect, danke :) hier ist die Arbeits jsfiddle http://jsfiddle.net/dr9c6/6/ist es richtig zu sagen, dass die im -Tag deklarierte Funktion die Funktion innerhalb des Controllers ist, während die andere, die '{data:}' bekommt, die Funktion des Anweisungsbereichs ist? – fusio

+1

@fusio, ja das ist richtig. –

+0

Ich habe ein ähnliches Problem ... Broadcasting von Controllern feuern meine Ereignisse nicht in Anweisungen ... Timeout löst das manchmal, aber nicht immer ... Auch die App ist ziemlich schwer und ich will nicht auf die verlassen Tatsache, dass die Zeit es immer lösen würde ... Gibt es einen anderen Weg, das zu tun? – ackuser