2015-12-21 4 views
17

Ich habe diese Frage gestellt, aber die spezifische Frage, die ich frage hat sich dramatisch verändert.Wie Instanziieren ng-Controller basierend auf einer Bedingung

Ich habe ein Stück Code:

<div ng-attr-controller="{{pings || 'PingsCtrl as pings' }}"> 
    <h1 ng-click="pings.press()">asdf</h1> 
    </div> 

Dieser Code in zwei HTML-Seiten eingespritzt wird. Eine Seite ruft bereits PingsCtrl an. Der andere nicht. Ich versuche wirklich, diesen Code DRY zu behalten, und ich möchte nur eine Referenz des obigen Codes haben.

Wie kann ich den obigen Code schreiben, um ng-controller zu generieren, wenn PingsCtrl nicht bereits instanziiert wurde.

Hier sind die zwei HTML-Seiten.

HTML

// First page 
<html ng-app="coolApp"> 
    <div ng-controller="PingsCtrl as pings"> 
    <div ng-attr-controller="{{pings || 'PingsCtrl as pings' }}"> 
     <h1 ng-click="pings.press()">asdf</h1> 
    </div> 
    </div> 
</html> 

// Second page 
<html ng-app="coolApp"> 
    <div ng-attr-controller="{{pings || 'PingsCtrl as pings' }}"> 
    <h1 ng-click="pings.press()">asdf</h1> 
    </div> 
</html> 

Javascript ist hier:

angular.module('coolApp', []) 

.controller('PingsCtrl', function() { 
    var vm = this; 

    vm.press = function() {alert(123)}; 
}) 

Was ist falsch und wie kann ich dieses Problem beheben?

+0

können Sie zusammen eine Plunker oder jsfiddle? – SoluableNonagon

+1

Erwägen Sie, allgemeine Funktionen in einen ** Werksdienst ** zu stellen. Sie sind Singletons und werden nur einmal automatisch geladen. Siehe https://docs.angularjs.org/guide/services#creating-services – georgeawg

+0

Ich versuche etwas zusammenzufügen. Der Code, den ich gepostet habe, ist jedoch alles, was benötigt wird. – jason328

Antwort

7

Verwenden Sie einfach einen Service. Es ist wirklich die beabsichtigte Struktur für gemeinsame Daten und Funktionalität zwischen den Seiten.

Ein Teil des Problems mit dem, was Sie versuchten, ist, ob Sie es schaffen, den Controller zu erhalten, hat Angular seine eigene Verwaltung, die Ihnen nicht folgen wird, und wird ohne Sie Komponenten aktualisieren. Sie werden in Dinge wie eine $scope stoßen, die nicht wirklich mit der Seite übereinstimmen, die Sie betrachten, und es verursacht mehr Probleme, als es wert ist.

+1

Ich stimme der Verwendung eines Dienstes zu. An diesem Punkt ist es reine Neugier, wie man das erreicht. – jason328

3

Ich habe eine Lösung, aber ich gebe auch die Bedenken anderer Leute bezüglich des Ansatzes wieder. Möglicherweise möchten Sie einen globalen Controller, den Sie auf den Körper für Dinge, die überall und in den meisten anderen Controllern passieren können, und rufen Sie nur durch. ZB

<body ng-controller="GlobalCtrl as gc"> 
    <h1 ng-click="gc.pingPress()"></h1> 
</body> 

Wie auch immer, hier ist, was ich gefunden habe.

<div ng-if="pings"> 
    <h1 ng-click="pings.press()">asdf</h1> 
</div> 
<div ng-if="!pings"> 
    <div ng-controller="PingsCtrl as pings"> 
     <h1 ng-click="pings.press()">asdf</h1> 
    </div> 
</div> 

Dies funktioniert, wenn es innerhalb oder außerhalb einer vorhandenen PingsCtrl gelöscht wird.

Hier ist ein Plünderer.

https://plnkr.co/edit/4x0kSazcg0g0BsqPKN9C?p=preview

+0

Ich sehe, dass der Controller in Ihrer Plunker-Demo neu installiert wird. Gibt es einen bestimmten Weg, um Controller-Wiederverwendung zu demonstrieren? Außerdem würde ich vorsichtig sein, globale Controller zu verwenden. IIRC, sie sollen veraltet und entmutigt sein. –

+0

Wenn Sie die Konsole auf dem Plocker öffnen, können Sie sehen, dass jede Seite den Controller nur einmal instanziiert, da ich die Instanziierung über die Konsole protokolliere. Außerdem schlage ich keine Funktion vor, die nicht nur ein regulärer Controller ist, sondern einfach globalen Controller. Nennen Sie es CommonCore als cc, wenn global eine Funktion bedeutet, die mir nicht bekannt ist. – matthewdaniel

+0

Vielleicht möchten Sie es noch einmal überprüfen. Die Protokollierung wird bei jeder Navigation instanziiert. –

1

Bitte überprüfen Sie meine Lösung, um zu sehen, wie die Daten zwischen den Controllern teilen

var app = angular.module('myApp', []); 
 

 
app.controller("aCtrl", function ($scope, PingList) { 
 
    $scope.addPing = function() { 
 
    PingList.add('Ping A'); 
 
    }; 
 
}); 
 

 
app.controller("bCtrl", function ($scope, PingList) { 
 
    $scope.addPing = function() { 
 
    PingList.add('Ping B'); 
 
    }; 
 
}); 
 

 
app.factory('PingList', function() { 
 
    var pings = ['Ping1', 'Ping2']; 
 

 
    return { 
 
    add: function(ping) { 
 
     pings.push(ping); 
 
    }, 
 
    get: function() { 
 
     return pings; 
 
    } 
 
    }; 
 
}); 
 

 
app.directive('pingList', function(PingList) { 
 
    return { 
 
    restrict: 'EA', 
 
    link: function($scope) { 
 
     $scope.pings = PingList.get(); 
 
     $scope.press = function(ping) { 
 
     alert(ping); 
 
     } 
 
    }, 
 
    template: '<ul><li ng-repeat="ping in pings" ng-click="press(ping)">{{ping}}</li></ul>' 
 
    }; 
 
});
a, li { 
 
    cursor: pointer; 
 
} 
 

 
a { 
 
    color: blue; 
 
    text-decoration: underline; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script> 
 

 
<div ng-app="myApp"> 
 
    <div ng-controller="aCtrl" style="float: left"> 
 
    <a ng-click="addPing()">click to add A ping</a> 
 
    <ping-list></ping-list> 
 
    </div> 
 
    <div ng-controller="bCtrl" style="float: right"> 
 
    <a ng-click="addPing()">click to add B ping</a> 
 
    <ping-list></ping-list> 
 
    </div> 
 
    <div style="clear: both"></div> 
 
</div>

Verwandte Themen