2016-08-09 25 views
1

Betrachten Sie den folgenden Code ein:ändern registrierte Komponente in Bootstrap-Periode in Angular 1.5

<!doctype html> 
<html> 
<body> 

    <main></main> 

    <script src="http://code.angularjs.org/snapshot/angular.js"></script> 
    <script src="script.js"></script> 

</body> 
</html> 

script.js

window.name = "NG_DEFER_BOOTSTRAP!"; 

angular.module('myApp', []); 

angular.module('myApp') 
.component('main', { 
    controller: function() { 
    this.greeting = 'World'; 
    }, 
    template: '<h1>Hello {{ $ctrl.greeting }} from main</h1>' 
}); 

angular.element(document).ready(function() { 
    angular.bootstrap(document, ['myApp']); 

    // Customizing comes here 
    // Should change the template to "Hello World from custom main" 

    angular.resumeBootstrap(); 
}); 

http://plnkr.co/edit/xftcWVXdFslptTGJiNM7?p=preview

Ich habe eine Basisanwendung und eine eigene "slot" auf der Serverseite, wo es möglich ist, Code zwischen angular.bootstrap(document, ['myApp']); und angular.resumeBootstrap(); einzufügen, um benutzerdefinierte Logik der App hinzuzufügen.

Dies funktioniert z. B. beim Hinzufügen neuer Module zur App.

Gibt es eine Möglichkeit, bereits registrierte Komponenten zu ändern? Ich möchte grundsätzlich in der Lage sein, die Signatur des registrierten Komponentenobjekts zu ändern.

Im obigen Beispiel und im Plunkr möchte ich einfach die "Vorlage" der bereits registrierten Komponente main auf etwas anderes ändern.

Beispiel bearbeitet: Added Controller und geändert plunkr

+0

dies scheint wie der falsche Ansatz, dies zu lösen. Die gängigste Methode zur Lösung dieses Problems wäre die Verwendung von 'templateUrl', das Festlegen dieser Eigenschaft auf eine Variable, die auf eine bestimmte Datei verweist, und das Aktualisieren der Eigenschaft, sodass sie bei Bedarf auf eine Datei verweist, die die neue Vorlage enthält. – Claies

+0

@Claies die Vorlage war nur für das minimale Beispiel. Ich möchte auch den Controller wenn möglich ändern - Bindungen - was auch immer. Ich möchte grundsätzlich auf das Komponentenoptionsobjekt zugreifen. – madflow

+0

Was ist der Anwendungsfall hier? Warum sollte man überhaupt eine Komponente für verkapselte Funktionalität erstellen, wenn man nur plant, die Funktionalität zu zerlegen und sie durch etwas anderes zu ersetzen? Scheint so, als würde das zu unkontrollierbarem Code führen, wo man einer Komponente nicht trauen kann, das zu tun, was sie bewirbt. – Claies

Antwort

1

ich zu sagen habe ich nicht einen solchen Anwendungsfall vorher gesehen. Normalerweise würden wir nur Direktiven dekorieren ... aber hier ist eine furchterregend-hacky-feeling Workaround.

Ihre Skripteinschleusung Logik in einer Weise ändern injizieren Sie JSON-Array alles enthält, die Sie außer Kraft setzen möchten, name und obj Paaren, wo name ist Komponente, die Sie ändern möchten und obj Objekt enthält alle Eigenschaften, die Sie hinzufügen möchten oder zu ersetzen.

Etwas wie folgt.

window.name = "NG_DEFER_BOOTSTRAP!"; 

var myApp = angular.module('myApp', []);  
myApp.component('main', { 
    template: '<h1>Initially nothing to bind :(</h1>' 
}); 

angular.element(document).ready(function() { 
    angular.bootstrap(document, ['myApp']); 

    // Customizing comes here in following format 
    var json = [{ 
    name: 'main', 
    obj: { 
     controller: function() { 
     this.goof = 'Yo!'; 
     }, 
     template: '<span>{{ $ctrl.goof }}</span>' 
    } 
    }]; 

    // Scary looking override logic !!1 
    myApp._invokeQueue.forEach(function(current) { 
    var obj = current[2]; 
    var name = obj[0]; 
    var replacement = _.findWhere(json, { name: name }); 

    if (replacement) { 
     for (var key in replacement.obj) { 
     obj[1][key] = replacement.obj[key]; 
     } 
    } 
    current = obj; 
    }); 

    angular.resumeBootstrap(); 
}); 

Yo

Gespaltene Plunker hier http://plnkr.co/edit/XQ1vZM

+1

Das ist es!: D Völlig hacky, wahrscheinlich total schlechteste Praxis - und total arbeiten !!! Vielen Dank! – madflow

0

Nicht sicher, ob dies ist, was Sie erreichen wollen, aber das ist möglich:

window.name = "NG_DEFER_BOOTSTRAP!"; 

var elem={template: '<h1>Hello from main</h1>'}; 

angular.module('myApp', []); 

angular.module('myApp') 
.component('main', elem); 

angular.element(document).ready(function() { 
    angular.bootstrap(document, ['myApp']); 

    // Customizing comes here 
    // Should change the template to "Hello from custom main" 
    //angular.module('myApp').component('main').template= '<h1>Hello from Custom main</h1>'; 
    elem.template = '<h1>Hello from Custom main</h1>'; 
    angular.resumeBootstrap(); 
}); 
+0

Die Vorlage diente lediglich zur Veranschaulichung des Beispiels. Mein Ziel ist es, das Komponentenobjekt zu ändern - nachdem es registriert wurde. – madflow

Verwandte Themen