AngularJS - 如何使用变量渲染部分? [英] AngularJS - How to render a partial with variables?

查看:28
本文介绍了AngularJS - 如何使用变量渲染部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,我在 car-list.html 中有一个部分,并且我想在具有不同汽车集合的多个地方渲染它.也许是这样的:

所有新车

<div ng-include="car-list.html" ng-data-cars="allCars | onlyNew"></div><h1>所有丰田</h1><div ng-include="car-list.html" ng-data-cars="allCars | make:toyota"></div>

与普通包含的主要区别在于部分不需要知道它正在显示的汽车列表.它给出了一系列汽车,并显示它们.可能喜欢:

<div ng-repeat="汽车中的汽车" ng-controller="CarListControl">{{car.year}} {{car.make}} {{car.model}}

解决方案

该指令在父作用域和子作用域中重命名的本地"变量之间提供 2 向数据绑定.它可以与诸如 ng-include 之类的其他指令结合使用,以实现出色的模板可重用性.需要 AngularJS 1.2.x

jsFiddle:AngularJS - 包含局部变量

<小时>

标记

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

发生了什么:

  • 这基本上是 ngInclude 指令的扩展,允许您从父作用域传入重命名的变量.ngInclude 根本不是必需的,但该指令旨在与它很好地配合使用.
  • 您可以附加任意数量的 locals-* 属性,这些属性都将被解析 &看着你作为 Angular 表达式.
    • 这些表达式可用于包含的部分,作为 $scope.locals 对象的属性附加.
    • 在上面的示例中,locals-cars="..." 定义了一个表达式,该表达式可用作 $scope.locals.cars.
    • 类似于 data-cars="..." 属性如何通过 jQuery 使用 .data().cars
<小时>

指令

EDIT 我已经重构以使用(并独立于)本机 ngInclude 指令,并将一些计算移到编译函数中以提高效率.

angular.module('withLocals', []).directive('withLocals', function($parse) {返回 {范围:真实,编译:函数(元素,属性,嵌入){//对于匹配 locals-* 的每个属性(驼峰式到 locals[A-Z0-9]),//捕获用于局部变量的键",以便我们以后可以//将其映射到 $scope.locals(在下面的链接函数中)var mapLocalsToParentExp = {};for(属性中的attr){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) {//找到初始化该指令的 $parent 作用域.//在控制器导致 $scope 深深嵌套在原始父级中的情况下很重要var $parent = $scope.$parent;而 (!$parent.hasOwnProperty(mapLocalsToParentExp[localKey])) {$parent = $parent.$parent;}返回函数(新值){$parse(mapLocalsToParentExp[localKey]).assign($parent, newValue);}};返回 {前:函数($scope,$element,$attributes){//设置 `$scope.locals` 哈希,以便我们可以映射表达式//从父作用域进入它.$scope.locals = {};for (localKey in mapLocalsToParentExp) {//对于每个本地键,$watch 提供的表达式并更新//$scope.locals 哈希(即属性`locals-cars` 有键//`cars` 和 $watch()ed 值映射到 `$scope.locals.cars`)$scope.$watch(mapLocalsToParentExp[localKey],功能(本地键){返回函数(新值,旧值){$scope.locals[localKey] = newValue;};}(本地密钥),真的);//还要观察本地值并传播任何更改//备份到父作用域.var parsedGetter = $parse(mapLocalsToParentExp[localKey]);如果(parsedGetter.assign){$scope.$watch('locals.'+localKey, updateParentValueFunction($scope, localKey));}}}};}};});

For example, I have a partial in car-list.html, and I want to render it in several places with different collections of cars. Maybe something like this:

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

The main difference from a normal include is that the partial doesn't need to know anything about which list of cars it's displaying. It's given an array of cars, and it displays them. Possibly like:

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

解决方案

This directive provides 2-way data-binding between the parent scope and renamed "local" variables in the child scope. It can be combined with other directives like ng-include for awesome template reusability. Requires AngularJS 1.2.x

jsFiddle: AngularJS - Include a partial with local variables


The Markup

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

What's going on:

  • This is basically an extension of the ngInclude directive to allow you to pass renamed variables in from the parent scope. ngInclude is NOT required at all, but this directive has been designed to work well with it.
  • You can attach any number of locals-* attributes, which will all be parsed & watched for you as Angular expressions.
    • Those expressions become available to the included partial, attached as properties of a $scope.locals object.
    • In the example above, locals-cars="..." defines an expression that becomes available as $scope.locals.cars.
    • Similar to how a data-cars="..." attribute would be available via jQuery using .data().cars

The Directive

EDIT I've refactored to make use of (and be independent of) the native ngInclude directive, and move some of the calculations into the compile function for improved efficiency.

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

                    }
                }
            };
        }
    };
});

这篇关于AngularJS - 如何使用变量渲染部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆