【问题标题】:How to show a dynamic content in the same page using Angularjs 1.6?如何使用 Angularjs 1.6 在同一页面中显示动态内容?
【发布时间】:2018-04-23 01:56:21
【问题描述】:

我是 Angular 的新手。我需要使用 AngularJS 1.6 从 JSON 文件呈现动态内容。这是我所拥有的。

News.json

   {
  "Articles": [
    {
      "Title": "News 1",    
      "Abstract": "News 1 abstract ...",
      "Body": "News 1 starts here.... ",
      "Comments": [
        {
          "comment 1" : "Comment 1 goes here",
          "comment 2" : "Comment 2 goes here",
          "comment 3" : "Comment 3 goes here"
        }]
    },

    {
      "Title": "News 2",
      "Abstract": "News 2 abstract ... ",
      "Body": "News 2 starts here...",
      "Comments": [
        {
          "comment 1" : "Comment 1 goes here",
          "comment 2" : "Comment 2 goes here"
        }]
    }    
  ]
}

Script.js

app.config(function ($routeProvider) {
    $routeProvider
        .when("/News", {
            templateUrl: "NewsViewer.html",
            controller: "showNews"
        });
});

app.controller("showNews", ["$scope", "$http", function ($scope, $http) {
    $http({
        method: 'GET',
        url: 'News/News.json'
    }).then(function success(data) {
        $scope.News = data.data;
    });
}]);

News.html

<div class="container-fluid">

    <div class="row">

        <div class="col-md-offset-1 col-md-6">
            <div ng-controller="NewsRendering">
                <div ng-repeat="NewsData in News.Articles">
                    <h3>{{NewsData.Title}}</h3>
                    <p>{{NewsData.Abstract}}</p>
                    <a data-ng-href="/AngularTask/NewsViewer.html">more</a>
                </div>
            </div>
        </div>

        <div class="col-md-4 questionnaire">
            <h3>Questionnaire of the day</h3>
        </div>

    </div>

</div>

NewsViewer.html

<div class="container-fluid">
    <div class="row">
        <div class="col-md-offset-1 col-md-6">
            <div ng-controller="showNews">
                <div>
                    <h3>{{News.Articles[0].Title}}</h3>
                    <p>{{News.Articles[0].Abstract}}</p>
                    <p>{{News.Articles[0].Body}}</p>
                </div>

                <div class="comments">
                    <h4>Comments</h4>
                    <hr>
                    <p>{{News.Articles[0].Comments[0]}}</p>
                </div>
            </div>
        </div>
    </div>
</div>

此代码运行良好,但此代码不是动态的。我的问题是如何使其动态化并可以在 json 文件中显示任何内容。在JS代码中我应该怎么做才能传递JSON文件的数组的索引。

如您所见,&lt;h3&gt;{{News.Articles[0].Title}}&lt;/h3&gt; 仅显示 JSON 文件的第一个标题。我需要写成&lt;h3&gt;{{News.Articles[index of whatever].Title}}&lt;/h3&gt;

注意:News.json 有大约 100,000 条记录。我做了两个,只是为了显示代码和描述问题。

【问题讨论】:

  • 看看 ng-repeat:w3schools.com/angular/ng_ng-repeat.asp(我不是官方 angular 文档的粉丝)。
  • 您问题中的代码是运行问题所需的一切吗?我只看到 HTML 和一些 JSON。
  • @Rob 是的,我不太了解 angularjs,列表可能是 100,000 或更多
  • 我根本看不到您在哪里提供了任何角度或 javascript 代码。您需要在此处发布问题代码的完整且最小的示例。 minimal reproducible example
  • 好多了。每次都这样做。

标签: javascript html angularjs json


【解决方案1】:

请在下面找到可行的解决方案

https://embed.plnkr.co/rbNAcVGtBvTjl9VhfFAl/

如果您需要更多信息,请告诉我。享受:)

已编辑

首先我们需要定义两条独立的路由,一条用于新闻,一条用于文章

$routeProvider.when("/News", {
    templateUrl: "News.html",
    controller: "NewsContoller"
}).when("/NewsViewer", {
    templateUrl: "NewsViewer.html",
    controller: "NewsViewerController"
})

如您所见,每个路由都有两个单独的控制器处理。

那么我们需要一个value服务在路由之间传递数据

angular.module('app').value('viewData', {})

点击more链接后,将viewData的值设置为该特定文章并重定向到/NewsViewer路由。并且,在 NewsViewerController 上,从 viewData 检索该值并将其传递给 $scope

模板:News.html

<div>
  <div ng-repeat="NewsData in News.Articles">
    <h3>{{NewsData.Title}}</h3>
    <p>{{NewsData.Abstract}}</p>
    <a href ng-click="showArticle(NewsData)">more</a>
  </div>
</div>

模板:NewsViewer.html

<div>
  <div>
    <h3>{{Article.Title}}</h3>
    <p>{{Article.Abstract}}</p>
    <p>{{Article.Body}}</p>
  </div>

  <div class="comments">
    <h4>Comments</h4>
    <hr>
    <p ng-repeat="(key, value) in Article.Comments[0]">
      {{value}}
    </p>
  </div>
</div>
<a ng-href="#!/News">All News</a>

控制器:NewsController

angular.module('app').controller('NewsContoller', function($scope, $http, viewData, $location) {
  $http({
    method: 'GET',
    url: 'News.json'
  }).then(function success(response) {
    $scope.News = response.data;
  });
  $scope.showArticle = function(article) {
    viewData.article = article;
    $location.path("/NewsViewer");
  }
})

控制器:NewsViewerController

angular.module('app').controller('NewsViewerController', function($scope, viewData) {
  $scope.Article = viewData.article;
})

plunker的链接在原始答案中。

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
  • 我是 stackoverflow 的新手,感谢您指导我。如果答案需要进一步修改,请告诉我。
【解决方案2】:

根据您的代码很少观察到:

  1. 这行代码&lt;a data-ng-href="/AngularTask/NewsViewer.html"&gt;more&lt;/a&gt; 将打破AngularJS 单页应用的宗旨(SPA)
  2. 使用ui-router 而不是ngRoute 会更好,因为ngRoute 已过时。
  3. 不要直接将用户重定向到 html 模板 (/AngularTask/NewsViewer.html),而是使用 ui-srefparams 更改视图的状态,并将 $index 作为参数值传递。

尝试以下方法以获得预期的结果:

News.html

  <div ng-repeat="NewsData in News.Articles">
    <h3>{{NewsData.Title}}</h3>
    <p>{{NewsData.Abstract}}</p>
    <a href="javascript:void(0)" ui-sref="newsdetails({index: $index})">more</a>
  </div>

routes.js:

$stateProvider
    .state('newsdetails', {
      url: '/news-details/:index',
      controller: 'showNews',
      templateUrl: 'NewsViewer.html'
    })
    ....

控制器:

.controller('showNews', function($scope, $stateParams) {
    $scope.indexVal = $stateParams.index; // getting index value passed from news.html
});

NewsViewer.html:

 <div ng-controller="showNews">
     <div>
         <h3>{{News.Articles[indexVal].Title}}</h3>
         <p>{{News.Articles[indexVal].Abstract}}</p>
         <p>{{News.Articles[indexVal].Body}}</p>
     </div>
 </div>

工作演示: https://plnkr.co/edit/jfzm00ksZMAC8sGGUZSR?p=preview

【讨论】:

  • 请您在 plunker 中编写您的代码,或者提供更多详细信息,因为我不知道如何应用您的解决方案
  • @HTMLMan 我用工作的 plnkr 更新了我的答案。谢谢
  • 感谢演示,但您使用 angular 1.2 和来自 github 的另一个我不知道它是什么。我也不能使用您使用的 github 选择 angular 1.2。
  • @HTMLMan 我只是将它们用于演示。您可以使用cdnnpm 在项目中使用这些库。
【解决方案3】:

我认为您需要的是使用 'ng-repeat' 显示数组文章和 '$http.get()' 根据需要“动态”加载 json.file。

【讨论】:

    【解决方案4】:

    您可以通过将新闻的索引传递给/News 路由来做到这一点。

    首先,更改News.html,使其按索引跟踪数据,然后将项目的索引附加到ng-href

    <div ng-repeat="NewsData in News.Articles track by $index">
      <h3>{{NewsData.Title}}</h3>
      <p>{{NewsData.Abstract}}</p>
      <a data-ng-href="/AngularTask/NewsViewer.html?index={{$index}}">more</a>
    </div>
    

    现在,对于每次访问,您都会在NewsViewer 路由中看到一个新的查询参数,即index

    其次,更改控制器,使其利用$routeParams传递的索引。

    app.controller("showNews", ["$scope", "$http", "$routeParams",
      function ($scope, $http, $routeParams) {
        $http({
            method: 'GET',
            url: 'News/News.json'
        }).then(function success(data) {
            $scope.News = data.data.Articles[$routeParams.index];
        });
    }]);
    

    这样,$scope.News 将包含驻留在传递索引上的文章。

    最后,更改NewsViewer.html,使其使用$scope.News

    <div class="container-fluid">
        <div class="row">
            <div class="col-md-offset-1 col-md-6">
                <div ng-controller="showNews">
                    <div>
                        <h3>{{News.Title}}</h3>
                        <p>{{News.Abstract}}</p>
                        <p>{{News.Body}}</p>
                    </div>
    
                    <div class="comments">
                        <h4>Comments</h4>
                        <hr>
                        <p>{{News.Comments[0]}}</p>
                    </div>
                </div>
            </div>
        </div>
    </div>
    

    对于 cmets,您可以再次使用 ng-repeat 指令来显示所有 cmets,逐个遍历它们。

    希望这能回答你的问题。

    【讨论】:

    • 它不工作。在url中显示索引的编号,但页面为空,不显示任何结果。
    • @HTMLMan -- 你能观察控制台是否有任何错误?
    • @HTMLMan -- 我看到 URL 变成了/AngularTask/NewsViewer.html,这在您的应用程序中不是有效的路由。您可以尝试将其更改为有效的吗?
    • 那我该怎么办
    • @HTMLMan -- 尝试将&lt;a data-ng-href="/AngularTask/NewsViewer.html?index={{$index}}"&gt;more&lt;/a&gt; 更改为&lt;a data-ng-href="/AngularTask/News?index={{$index}}"&gt;more&lt;/a&gt;。请确保/AngularTask/ 是有效路由。
    【解决方案5】:

    我想这就是你想要的

    NewsViewer.html

            <div class="container-fluid">
        <div class="row">
            <div class="col-md-offset-1 col-md-6">
                <div ng-controller="showNews">
                    <div>
                        <div>
                            <h3>{{selectedArticle.Title}}</h3>
                            <p>{{selectedArticle.Abstract}}</p>
                            <p>{{selectedArticle.Body}}</p>
                        </div>
    
                        <div class="comments">
                            <h4>Comments</h4>
                            <hr>
                            <div ng-repeat="comment in selectedArticle.Comments">
                                <p ng-repeat="(key, value) in comment">
                                    <strong>{{key}}</strong>: {{value}}
                                </p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    

    【讨论】:

    • 这将列出所有 JSON 文件。虽然我需要展示一个新的取决于 newsviewer.html 文件的内容
    • 然后只删除最外层的 foreach 并根据路由向 HTML 提供单个 Artical。
    【解决方案6】:

    你需要结合rootScope使用路由服务来保存选中的对象。我为你做了一个简单的例子:

    angular
    .module('myApp', ['ngRoute'])
    .config(['$routeProvider', function($routeProvider){
        $routeProvider
            .when('/list', {
                templateUrl: 'pages/list.html',
                controller: 'listController'
            })
            .when('/details', {
                templateUrl : 'pages/details.html',
                controller: 'displayController'
            })
            .otherwise({redirectTo: '/list'});
    }])
    .controller('listController', function($scope, $rootScope) {
        var myObject = {
            Listoflinks: [{
                "Title": "Link 1",
                "Abstract": "abstract is here ....",
                "Body": "Body is here ...",
            },
            {
                "Title": "Link 1",
                "Abstract": "abstract is here ....",
                "Body": "Body is here ...",
            }]
        }
        $rootScope.detail = myObject.Listoflinks[0];
    })
    .controller('displayController', function($scope, $rootScope) {
        $scope.detail = $rootScope.detail;
    });
    

    https://plnkr.co/edit/0SYnFcjlgGyTowlcpvgz?p=catalogue

    【讨论】:

    • 假设你有 100,000 个列表,我该怎么办?
    • 迭代列表并将对应的对象发送到rootScope。
    • 请您修改代码以做到这一点,因为我不知道如何在角度做到这一点
    • @HTMLMan 检查这个分叉的 plunker plnkr.co/edit/EvqvDf77sfuShOFh0MZt?p=preview
    猜你喜欢
    • 2014-08-24
    • 1970-01-01
    • 2015-07-26
    • 1970-01-01
    • 1970-01-01
    • 2016-11-05
    • 1970-01-01
    • 2020-01-14
    • 2018-08-07
    相关资源
    最近更新 更多