angularjs

ng-bind-html angularjs



AngularJS-¿Cómo hacer un parcial con variables? (3)

Por ejemplo, tengo un parcial en car-list.html , y quiero representarlo en varios lugares con diferentes colecciones de autos. Tal vez algo como esto:

<h1>All New Cars</h1> <div ng-include="car-list.html" ng-data-cars="allCars | onlyNew"></div> <h1>All Toyotas</h1> <div ng-include="car-list.html" ng-data-cars="allCars | make:toyota"></div>

La diferencia principal de una inclusión normal es que el parcial no necesita saber nada sobre qué lista de autos está mostrando. Se le da una serie de coches, y los muestra. Posiblemente como

<!-- car-list.html --> <div ng-repeat="car in cars" ng-controller="CarListControl"> {{car.year}} {{car.make}} {{car.model}} </div>


Esta directiva proporciona un enlace de datos bidireccional entre el ámbito principal y las variables "locales" renombradas en el ámbito secundario. Se puede combinar con otras directivas como ng-include para una reutilización increíble de la plantilla. Requiere AngularJS 1.2.x

jsFiddle: AngularJS - Incluir un parcial con variables locales

El marcado

<div with-locals locals-cars="allCars | onlyNew"></div>

Que esta pasando:

  • Esto es básicamente una extensión de la directiva ngInclude para permitirle pasar variables renombradas desde el ámbito principal. ngInclude NO se requiere en absoluto, pero esta directiva ha sido diseñada para funcionar bien con ella.
  • Puede adjuntar cualquier número de atributos locals-* , que se analizarán y observarán para usted como expresiones angulares .
    • Esas expresiones están disponibles para el parcial incluido, que se adjunta como propiedades de un objeto $scope.locals .
    • En el ejemplo anterior, locals-cars="..." define una expresión que queda disponible como $scope.locals.cars .
    • Similar a cómo un atributo data-cars="..." estaría disponible a través de jQuery usando .data().cars

La directiva

EDITAR He refaccionado para hacer uso de (y ser independiente de) la directiva nativa ngInclude , y mover algunos de los cálculos a la función de compilación para mejorar la eficiencia.

angular.module(''withLocals'', []) .directive(''withLocals'', function($parse) { return { scope: true, compile: function(element, attributes, transclusion) { // for each attribute that matches locals-* (camelcased to locals[A-Z0-9]), // capture the "key" intended for the local variable so that we can later // map it into $scope.locals (in the linking function below) var mapLocalsToParentExp = {}; for (attr in attributes) { if (attributes.hasOwnProperty(attr) && /^locals[A-Z0-9]/.test(attr)) { var localKey = attr.slice(6); localKey = localKey[0].toLowerCase() + localKey.slice(1); mapLocalsToParentExp[localKey] = attributes[attr]; } } var updateParentValueFunction = function($scope, localKey) { // Find the $parent scope that initialized this directive. // Important in cases where controllers have caused this $scope to be deeply nested inside the original parent var $parent = $scope.$parent; while (!$parent.hasOwnProperty(mapLocalsToParentExp[localKey])) { $parent = $parent.$parent; } return function(newValue) { $parse(mapLocalsToParentExp[localKey]).assign($parent, newValue); } }; return { pre: function($scope, $element, $attributes) { // setup `$scope.locals` hash so that we can map expressions // from the parent scope into it. $scope.locals = {}; for (localKey in mapLocalsToParentExp) { // For each local key, $watch the provided expression and update // the $scope.locals hash (i.e. attribute `locals-cars` has key // `cars` and the $watch()ed value maps to `$scope.locals.cars`) $scope.$watch( mapLocalsToParentExp[localKey], function(localKey) { return function(newValue, oldValue) { $scope.locals[localKey] = newValue; }; }(localKey), true ); // Also watch the local value and propagate any changes // back up to the parent scope. var parsedGetter = $parse(mapLocalsToParentExp[localKey]); if (parsedGetter.assign) { $scope.$watch(''locals.''+localKey, updateParentValueFunction($scope, localKey)); } } } }; } }; });


Me gustaría ofrecer mi solución , que está en un diseño diferente.

El uso ideal para ti es:

<div ng-include-template="car-list.html" ng-include-variables="{ cars: (allCars | onlyNew) }"></div>

El objeto ng-include-variables se agrega al ámbito local. Por lo tanto, no ensucia tu ámbito global (o principal).

Aquí está su directiva:

.directive( ''ngIncludeTemplate'' () -> { templateUrl: (elem, attrs) -> attrs.ngIncludeTemplate restrict: ''A'' scope: { ''ngIncludeVariables'': ''&'' } link: (scope, elem, attrs) -> vars = scope.ngIncludeVariables() for key, value of vars scope[key] = value } )

(Está en Coffeescript)

OMI, ng-include es un poco extraño. Tener acceso al ámbito global disminuye su reutilización.


Puedes lograrlo fácilmente con una directive .

Algo como eso:

angular.module(''myModule'') .directive(''cars'', function () { return { restrict: ''E'', scope: { ''cars'': ''=data'' }, template: "<div ng-repeat=''car in cars''>/n" + " {{car.year}} {{car.make}} {{car.model}}/n" + "</div>" }; });

Entonces puedes usarlo así:

<h1>All New Cars</h1> <cars data="allCars | onlyNew"></cars> <h1>All Toyotas</h1> <cars data="allCars | make:toyota"></cars>

Puede encontrar más información sobre las directivas here .