【问题标题】:Nested directive with no template but ng-repeat in parent directive没有模板但在父指令中重复 ng-repeat 的嵌套指令
【发布时间】:2016-02-17 12:03:37
【问题描述】:

我试着解释我的问题:

我有一个包含元素列表的自定义指令(此时元素是自定义指令,但我不知道它是否正确)。 对于每个元素,我需要获取一些值并将这些值放在父指令中,其中我有两个不同的 ng-repeat。 也许有人认为我应该在嵌套指令中使用这些值并在父级中使用 ng-transclude。但我不能,因为嵌套指令应该有两个不同的模板。 可能不是很清楚,所以我让你看看我的代码:

Index.html(我使用指令的地方)

<rh-portfolio>
    <rh-portfolio-image id="portfolio-item-six" url="images/portfolio/thumbnail/img-01.jpg" description="" category="construction"></rh-portfolio-image>
    <rh-portfolio-image id="portfolio-item-seven" url="images/portfolio/thumbnail/img-02.jpg" description="" category="construction"></rh-portfolio-image>
    <rh-portfolio-image id="portfolio-item-eight" url="images/portfolio/thumbnail/img-03.jpg" description="" category="construction"></rh-portfolio-image>
    <rh-portfolio-image id="portfolio-item-nine" url="images/portfolio/thumbnail/img-04.jpg" description="" category="construction"></rh-portfolio-image>
    <rh-portfolio-image id="portfolio-item-ten" url="images/portfolio/thumbnail/img-05.jpg" description="" category="construction"></rh-portfolio-image>
</rh-portfolio>

portofolio.js(父指令和嵌套指令所在的位置)

.directive('rhPortfolio', function () {
    return {
        restrict: 'E',
        replace: true,
        templateUrl: '/partial_views/directives/templates/portfolio.html',
        scope: {},
        controller: ['$scope', function ($scope) {
            var images = $scope.images = [];

            $scope.select = function (image) {
                angular.forEach(images, function (image) {
                    image.selected = false;
                });
                image.selected = true;
            };

            this.addImage = function (image) {
                if (image.length === 0) {
                    $scope.select(image);
                }
                images.push(image);
            };
        }]
    };
})
.directive('rhPortfolioImage', function () {
    return {
        restrict: 'E',
        replace: true,
        require: '^^rhPortfolio',
        link: function (scope, element, attrs, portfolioCtrl) {
            portfolioCtrl.addImage(scope);
        }
    };
});

最后,指令的模板

...
<div class="tab-content tg-img-border"><!--portfolio-item-one-->
    <div role="tabpanel" class="tab-pane fade in active" ng-repeat="image in images" id="{{ image.id }}">
        <figure><img src="{{ image.url }}" alt="{{ image.description }}"></figure>
    </div>
</div>
... <!-- Here in the middle, there is a lot of code that must not be replicated -->  
<div role="presentation" ng-repeat="image in images" class="active portfolio-item grid-item {{ image.category }}">
    <div class="product-box">
        <a href="#{{ image.id }}" aria-controls="{{ image.id }}" role="tab" data-toggle="tab">
            <figure><img src="{{ image.url }}" alt="{{ image.description }}"></figure>
            ...
        </a>
    </div>
</div>
...

如您所见,嵌套指令不会有唯一的模板。所以我决定使用两个不同的 ng-repeat。在这两个 ng-repeat 之间,有一段代码是不应该重复的,也就是说,无论如何都必须在父指令里面。

无论如何,我的代码不起作用...我也不明白为什么.. perhpas 因为尝试使用在父控制器中定义的“图像”元素的属性,但它是从嵌套的指令。

编辑 在这里您可以看到问题。在页面底部,您应该看到带有图像的投资组合...但是有些东西不起作用: http://simonerh.altervista.org/_test/

在这里你可以看到没有 Angularjs 的版本(所以,我期望看到的): http://simonerh.altervista.org/

EDIT2 这里是 Plunker 版本 http://plnkr.co/edit/nf2bVkNujtb69WRfs0I7?p=preview

谁能帮帮我? 谢谢

【问题讨论】:

  • “不工作” 不是一个正确的问题陈述,它为任何人提供任何真正的故障排除信息来工作。这可能意味着从空白页到次要细节的任何内容。用所有相关的调试细节更新问题和演示也很有帮助
  • 这很难解释..我看不到图像...从 Chrome 的“开发者工具”中我只看到了这个错误:Failed to load resource: the server responded with a status of 404 (Not Found)http://localhost:2060/%7B%7B%20image.url%20%7D%7D 其中image.url 来自你的角度可以从指令模板中看到
  • 等等,我尝试发布该网站,以便您可以看到我的指令的效果。但是我认为我认为指令的方式完全错误
  • 如果您希望人们能够帮助 fork 代码更改,那么在 plunker 中的简单演示会更好
  • 我编辑了我的问题.. 我放了一个链接,您可以直接在我正在做的网站上看到错误。同时,我会尝试在 plunker 上做一个演示。

标签: angularjs angularjs-ng-repeat directive angularjs-ng-transclude


【解决方案1】:

你有三个问题。

  1. 您没有在指令rh-portfolio-image 中传递参数。如idURL
  2. 您的指令rh-portfolio-image 不调用,因为指令rh-portfolio 具有属性replace:true
  3. 您不使用transclude:true。有关ng-transclude 的更多详细信息。

我正在更改您的模板portfolio.html。请查看punker。这不是完成的解决方案,但它向您展示了如何创建指令。

var renovahaus = angular.module("renovahaus", [])
.directive('rhPortfolio', function () {
        return {
            restrict: 'E',
            replace:true,
            transclude:true,
            template: '<section class="tg-main-section tg-haslayout bg-white">  <pre>images = {{images|json}}</pre><div  ng-transclude></div></section>',
            scope: {},
            controller: ['$scope', function ($scope) {
                var images = $scope.images = [];

                $scope.select = function (image) {
                    angular.forEach(images, function (image) {
                        image.selected = false;
                    });
                    image.selected = true;
                };

                this.addImage = function (image) {
                    if (image.length === 0) {
                        $scope.select(image);
                    }
                    images.push(image);
                };
            }]
        };
    })
    .directive('rhPortfolioImage', function () {
        return {
            restrict: 'E',
            //replace: true,
            require: '^^rhPortfolio',
            scope: {id:"="},
            template:'<span>{{id}}</span>',
            link: function (scope, element, attrs, portfolioCtrl) {
                console.log(1);
                portfolioCtrl.addImage(scope);
            }
        };
    }) .directive('rhPortfolioIm', function () {
        return {
            restrict: 'E',
            scope: {id:"@"},
            require: '^rhPortfolio',
            template:'<span>{{id}}</span>',
            link: function (scope, element, attrs,portfolioCtrl) {
                portfolioCtrl.addImage(scope);
            }
        };
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html class="no-js" lang="">

<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>BootStrap HTML5 CSS3 Theme</title>
  <meta name="description" content="" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <link rel="apple-touch-icon" href="apple-touch-icon.png" />
  <script data-require="jquery@1.11.3" data-semver="1.11.3" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
  <link data-require="bootstrap@3.3.5" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
  <link data-require="bootstrap@3.3.5" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.3.5/cosmo/bootstrap.min.css" />
  <link data-require="bootstrap@3.3.5" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" />
  <script data-require="bootstrap@3.3.5" data-semver="3.3.5" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
  <script data-require="angular.js@1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>

  <link rel="stylesheet" href="style.css" />
  <script src="app.js"></script>
  <script src="portfolio.js"></script>
</head>

<body class="home" ng-app="renovahaus">
  <rh-portfolio>
    <rh-portfolio-im id="'portfolio-item-six'"></rh-portfolio-im>
    <rh-portfolio-im id="'portfolio-item-seven'"></rh-portfolio-im>
  </rh-portfolio>
</body>

</html>

附:在标签&lt;div ng-transclude&gt;&lt;/div&gt; 中包含指令rhPortfolioIm

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-09
    • 2013-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多