not angularjs angularjs-scope

not - rootscope angularjs



AngularJS: ¿cómo puedo crear un alcance nuevo y aislado mediante programación? (5)

Los siguientes son los pasos:

  1. Agregue su HTML al DOM utilizando var comiledHTML = angular.element(yourHTML);
  2. Cree un nuevo Ámbito si desea var newScope = $rootScope.$new();
  3. Llame a $ comile (); función que devuelve la función de enlace var linkFun = $compile(comiledHTML);
  4. Enlace el nuevo ámbito llamando a linkFun var finalTemplate = linkFun(newScope);
  5. Añade finalTemplate a tu DOM YourHTMLElemet.append(finalTemplate);

Quiero crear una AlertFactory con Angular.factory. Definí una plantilla html como seguir

var template = "<h1>{{title}}</h1>";

El título lo proporciona el controlador de llamadas y se aplica de la siguiente manera

var compiled = $compile(template)(scope); body.append(compiled);

Entonces, ¿cómo puedo pasar el alcance aislado del controlador a la fábrica? Estoy usando el código de seguimiento del controlador

AlertFactory.open($scope);

Pero $ scope es la variable de alcance del controlador global. Solo quiero pasar un pequeño alcance para la fábrica con solo propiedad del título.

Gracias.


Puede crear un nuevo alcance manualmente.

Puede crear un nuevo ámbito desde $rootScope si lo inyecta, o solo desde el alcance de su controlador; esto no debería importar, ya que lo aislará.

var alertScope = $scope.$new(true); alertScope.title = ''Hello''; AlertFactory.open(alertScope);

La clave aquí está pasando true a $new , que acepta un parámetro para isolate , lo que evita heredar el alcance del padre.

Se puede encontrar más información en: http://docs.angularjs.org/api/ng.$rootScope.Scope#$new


Si solo necesita interpolar elementos, use el servicio $interpolate lugar de $ compile, y luego no necesitará un alcance:

myApp.factory(''myService'', function($interpolate) { var template = "<h1>{{title}}</h1>"; var interpolateFn = $interpolate(template); return { open: function(title) { var html = interpolateFn({ title: title }); console.log(html); // append the html somewhere } } });

Controlador de prueba:

function MyCtrl($scope, myService) { myService.open(''The Title''); }

Fiddle


Supongo que cuando hablas de un alcance aislado estás hablando de una directiva.

Aquí hay un ejemplo de cómo hacerlo. http://jsfiddle.net/rgaskill/PYhGb/

var app = angular.module(''test'',[]); app.controller(''TestCtrl'', function ($scope) { $scope.val = ''World''; }); app.factory(''AlertFactory'', function () { return { doWork: function(scope) { scope.title = ''Fun''; //scope.title = scope.val; //notice val doesn''t exist in this scope } }; }); app.controller(''DirCtrl'', function ($scope, AlertFactory) { AlertFactory.doWork($scope); }); app.directive(''titleVal'',function () { return { template: ''<h1>Hello {{title}}</h1>'', restrict: ''E'', controller: ''DirCtrl'', scope: { title: ''='' }, link: function() { } }; });

Básicamente, conecte un controlador a una directiva que haya definido un alcance aislado. El alcance inyectado en el controlador de la directiva será un alcance aislado. En el controlador de directivas puede inyectar su AlertFactory con la que puede pasar el alcance de aislamiento.


echa un vistazo a mi plunkr. Estoy generando programáticamente una directiva de widgets con una directiva de renderizado.

https://plnkr.co/edit/5T642U9AiPr6fJthbVpD?p=preview

angular .module(''app'', []) .controller(''mainCtrl'', $scope => $scope.x = ''test'') .directive(''widget'', widget) .directive(''render'', render) function widget() { return { template: ''<div><input ng-model="stuff"/>I say {{stuff}}</div>'' } } function render($compile) { return { template: ''<button ng-click="add()">{{name}}</button><hr/>'', link: linkFn } function linkFn(scope, elem, attr) { scope.name = ''Add Widget''; scope.add = () => { const newScope = scope.$new(true); newScope.export = (data) => alert(data); const templ = ''<div>'' + ''<widget></widget>'' + ''<button ng-click="export(this.stuff)">Export</button>'' + ''</div>''; const compiledTempl = $compile(templ)(newScope); elem.append(compiledTempl); } } }