2013-08-02 4 views
5

Ecco lo jsfiddle che esemplifica la mia situazione.Ricezione di broadcast e chiamata alle funzioni del controller da ambito/direttiva isolati in AngularJS?

Prima di tutto, è questo il modo corretto di creare direttive con le dimensioni ricevute? Quindi, ogni direttiva dovrebbe essere isolata dalle altre .. quindi sto usando scope: {}.

Il problema sta chiamando le funzioni che sono nel controller .. e pare che non riceve la trasmissione sia ..

Sono sicuro che questo è un problema banale .. Sono nuovo di angolare :)

ho una pagina in cui carico un numero di componenti con ng-repeat:

<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> 

Il controllore:

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"); 
    }; 
}). 

e la direttiva:

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 
     }; 
    }); 

risposta

16

Il controllore esegue prima che la funzione di collegamento, quindi la trasmissione viene inviato troppo presto. È possibile ritardare questo usando $timeout:

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

di chiamare un metodo di controllo da una direttiva con un ambito isolato, è necessario specificare il metodo come argomento:

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

ed è necessario utilizzare il & sintassi nella direttiva:

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

per passare parametri a quella funzione di callback/regolatore, è necessario utilizzare la sintassi corretta: 012.313.. Nel violino, ho usato solo argomento, e superato i due parametri in un array invece:

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

fiddle

+0

perfette, grazie :) qui è la lavorazione jsfiddle http://jsfiddle.net/dr9c6/6/è corretto dire che la funzione dichiarata nel tag è la funzione all'interno del controller, mentre l'altra che ottiene '{data:}' è la funzione dell'ambito della direttiva? – fusio

+1

@fusio, sì è corretto. –

+0

Sto avendo un problema simile ... la trasmissione dai controller non licenzia i miei eventi in direttive ... Timeout a volte risolve questo problema ma non sempre ... Inoltre, l'app è piuttosto pesante e non voglio fare affidamento sul Infatti quel tempo avrebbe sempre risolto il problema ... C'è un altro modo per farlo? – ackuser