41

我的 AngularJS 应用程序中有一个页面,我想在其中包含相同的 html 部分,但具有不同的变量。如果我在我的 main 中这样做html

<div id="div1" ng-include src="partials/toBeIncluded.html onload="var='A'">
<div id="div2" ng-include src="partials/toBeIncluded.html onload="var='B'">

看起来toBeIncluded.html

<div>{{var}}</div>

两者div看起来像

<div id="div1"><div>B</div></div>
<div id="div2"><div>B</div></div>

onload我想这与所有 ng-includes 都需要相同的事实有关。那么如何将不同的变量发送到每个不同的包含?

4

15 回答 15

40

onload每次加载新的部分时,传递给的表达式都会进行评估。在这种情况下,您将更改var两次的值,因此在加载两个部分时,当前值将是B

您想将不同的数据传递给每个部分/模板(底层 html 文件相同)。为了实现这一点,正如 Tiago 所提到的,您可以使用不同的控制器来实现。例如,考虑以下

<body ng-controller='MainCtrl'>    
  <div ng-include src='"toBeIncluded.html"' ng-controller='ctrlA' onload="hi()"></div>
  <div ng-include src='"toBeIncluded.html"' ng-controller='ctrlB' onload="hi()"></div>
</body>

在这里,我们有两个部分,每个部分都有自己的范围,由它们自己的控制器(ctrlActrlB)管理,两个子范围都是MainCtrl. 该函数hi()属于 的范围,MainCtrl将运行两次

如果我们有以下控制器

app.controller('MainCtrl', function($scope) {
  $scope.msg = "Hello from main controller";
  $scope.hi= function(){console.log('hi');};
});

app.controller('ctrlA', function($scope) {
  $scope.v = "Hello from controller A";
});

app.controller('ctrlB', function($scope) {
  $scope.v = "Hello from controller B";
});

的内容toBeIncluded.html

<p>value of msg = {{msg}}</p>
<p>value of v = {{v}} </p>

生成的 html 将类似于以下内容

<p>value of msg = Hello from main controller</p>
<p>value of v = Hello from main controller A </p>

<p>value of msg = Hello from main controller</p>
<p>value of v = Hello from controller B </p>

此处示例:http ://plnkr.co/edit/xeloFM?p=preview

于 2012-12-11T02:19:08.260 回答
27

就像马克所说的那样,但为了简化一点并使其更加“即时”,请使用以下内容:

<div ng-repeat="name in ['John']" ng-include="'name-template.html'"></div>
<div ng-repeat="name in ['Jack']" ng-include="'name-template.html'"></div>

<script type="text/ng-template" id="name-template.html">
   <div>The name is {{ name }}</div>
<script>

这里的例子:http: //jsfiddle.net/Cndc6/4/

于 2013-12-17T16:49:07.000 回答
20

在您对@jm- 的回答的评论中,您提到您想在 ng-repeat 中加载您的部分内容。为此,请在 $scope 上创建一个数组,并在该数组上设置唯一值:

$scope.partialStuff = [ 'p1', 'p2', 'p3' ];

在你的局部某处:

{{partialVar}}

的HTML:

<div ng-repeat="partialVar in partialStuff">
   <div ng-include src="'partials/toBeIncluded.html'"></div>
</div>

小提琴

于 2012-12-11T15:36:33.497 回答
10

我可能是错的,但使用指令不是更好吗?

.directive('foobar', [function factory() {
    return {
        restrict: 'E',
        replace: true,
        templateUrl: '/toBeIncluded.html',
        scope: {
            "var": "="
        }
    };
}]);

还有你的 HTML

<div ng-repeat="var in data">
    <foobar var="var"></foobar>
</div>

现在 foobar 元素应该替换为您的模板。每个都有自己的范围。

于 2014-03-13T07:40:04.517 回答
1

具体来说,ng-init 和 onload 表达式是在作用域中计算的,而不是由 nginclude 创建的子作用域。因此,您var在父作用域上分配了两次值,这两次都发生在这些 ng-includes 内的内容被加载编译和评估之前。创建每个子作用域时,它都从父作用域继承,其中 var='B'。

于 2013-04-26T18:29:27.520 回答
1

考虑你的局部变量 foo ,

然后你会像这样传递 foo :

<ng-include src="'partials/foo-part.html'" onLoad="foo='bar'"></ng-include>

为了获得更多的浏览器兼容性,您可以像这样传递它:

<div ng-include src="'partials/foo-part.html'" onLoad="foo='bar'"></div>

你也可以使用onInclude="foo='bar'"代替onLoad

plnkr.co/edit/GHRNyAMBKLvgtf3NFSRu?p=info

于 2015-06-27T05:45:23.297 回答
0

不会为所有 ng-includes 调用相同的“onLoad”。最有可能的是,var 设置为 A,然后设置为 B。问题是,它在两个包含之间共享,因为它们在同一范围内。'var' 作为 angularJS 中的模型,是依赖于范围的。

为了使您的部分具有单独的值,它们必须各自具有自己的范围。最简单的方法是设置一个控制器或指令并将其分配给 ng-include 所在的 Dom 元素,并在该范围内设置您的值。

于 2012-12-11T01:27:58.117 回答
0

我遇到了同样的问题,我找到了一种方法来实现我想要的,当然它看起来不是很漂亮,但仍然。

我使用了 ng-repeat ,它将创建一个新的范围来包含两次具有不同值的相同模板,如下所示(虚拟示例):

<script type="text/ng-template" id="mod-edito.html">
<div class="mod-edito__media">
    <img ng-src="{{ edito.cover.src }}" />
</div>
</script>

<div>
    <ng-include ng-repeat="edito in [edito_object]" src="'mod-edito.html'"></ng-include>
    ...
    <ng-include ng-repeat="edito in [edito_other]" src="'mod-edito.html'"></ng-include>
</div>

这可以接受吗?大概吧。

于 2014-08-08T09:26:29.940 回答
0

我一直在寻找替代方案,我想要一个 js 对象将一些参数发送到包含的部分中。这是@denis-pshenov 制作的进化版。您可以使用控制器来填充数据,也可以使用 ng-init。

基本上,像这样的东西,

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

myApp.controller('Controller', function($scope) {
    $scope.ourData = [ { name : 'John', address : 'Paradise' } ];
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="Controller">
    <div ng-repeat="data in ourData" ng-include="'partial.html'"></div>
    
    <div ng-init="ourData2 = [ { name : 'Jack', address : 'Paradise' } ]" />
    <div ng-repeat="data in ourData2" ng-include="'partial.html'"></div>
    
</div>

<script type="text/ng-template" id="partial.html">
   <div>The name is {{ data.name }} and the address is {{ data.address }} </div>
</script>

于 2014-09-20T14:46:13.500 回答
0

有一种方法可以创建通用的可重用指令。

这是我的一位同事提出的(受Knockout.js启发)。

指示:

(function () {
    'use strict';

    angular
        .module('directives')
        .directive('ngWith', ngWith);

    function ngWith() {
        return {
            restrict: 'A',
            replace: true,
            scope: {
                model: '=',
                template: '@'
            },
            template: '<div data-ng-include="template"></div>',
        };
    }
})();

用法:

<div data-ng-with="" data-model="parentObj.childObj.whatEver" data-template='my-template.html'></div>
于 2014-10-06T15:51:56.840 回答
0

请注意,如果您在 ng-repeat 中包含部分内容,您仍然可以访问父作用域的 $index。只需在部分中包含 {{$index}}。

于 2014-10-29T16:01:27.993 回答
0

使用 onload 不是一个干净的解决方案,因为它会在全局范围内乱扔垃圾。如果你有更复杂的东西,它就会开始失败。

使用新指令而不是 ng-include是一种更简洁的解决方案。

理想的用法如下所示:

<div ng-include-template="partials/toBeIncluded.html" ng-include-variables="{ var: 'A' }"></div>
<div ng-include-template="partials/toBeIncluded.html" ng-include-variables="{ var: 'B' }"></div>

该指令是:

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

您可以看到该指令不使用全局范围。相反,它从 ng-include-variables 读取对象并将这些成员添加到它自己的本地范围内。

ng-include 不是那么可重用,因为它可以访问全局范围。这有点奇怪。

我希望这是你想要的;它干净而通用。

于 2015-10-25T17:56:24.730 回答
0

您可以参考特征单个值,例如$scope.a = 'test'和对象,$scope.a = {a.test};并使用不同的范围来定义可见性区域。

来自 ng-if 文档。

请注意,当使用 ngIf 删除元素时,它的作用域将被破坏,而当元素恢复时会创建一个新作用域。

Simpe 解决方案是ng-if将您的静态内容包含并定义到ng-init指令中。

<div ng-if="<any-true-expression>" ng-init="val='First'" ng-include="'html/common.html'"</div>

<div ng-if="<any-true-expression>" ng-init="val='Second'" ng-include="'html/common.html'"</div>

在这种情况下,它将以不同的值显示,例如

{{val}} shows >>
First
Second

此内容是静态的,因为 val 是对值的简单引用。

如果您想拥有依赖于一些常见范围值的动态可更改页面,您需要销毁并重新创建使用指令时创建的范围ng-if。像这样:

<div id="wrapper" ng-if="orders_client">
       <div id="client-orders" ng-init="orders = orders_client" ng-include="'html/pages/parts/orders-view.html'"></div>
</div>

$scope.orders_client = null;
   /*recreate content table*/
     $timeout(function () {
        $rootScope.general.showPreloader = false;
        $scope.orders_client = $scope.baseData.clients[newClient];
     }, 500);

在这种情况下,具有先前数据的范围将被销毁,并且将创建具有新数据的新范围。重新创建新范围需要500ms的时间。如果存在更好的捕获,请写。

于 2017-12-29T17:04:42.400 回答
0

ng-if=true每次加载部分通过时,您都可以使用强制新范围ng-include

你的代码看起来像

<div id="div1" ng-include src="partials/toBeIncluded.html onload="var='A'" ng-if="true">
<div id="div2" ng-include src="partials/toBeIncluded.html onload="var='B'" ng-if="true">

可以在这个plunker找到一个例子

此处引用相同想法的另一个答案

于 2020-02-29T20:08:17.970 回答
-3

只需将每个 ng-include 放在自己<div>的下面,如下所示:

<div>
  <div id="div1" ng-include src="partials/toBeIncluded.html onload="var='A'"/>
</div>
<div>
  <div id="div2" ng-include src="partials/toBeIncluded.html onload="var='B'"/>
</div>

然后,每个包含的 HTML 都将var在其自己的范围内拥有自己的 HTML。

于 2013-11-21T08:04:23.070 回答