AngularJS加载JSON数据,然后从中解析/加载HTML

时间:2016-05-16 18:36:48

标签: javascript html angularjs

首先,这是我第一次使用Angular。

我的目标是,我有一个通知列表,我必须以limitTo限制,所以元素限制为三个,点击按钮后,其余部分应该加载。

我不明白该怎么做:

  • 设置“视图”以及如何应用ng-repeat
  • 加载我已设置的JSON数据,并以某种方式将其解析为从* json到视图的纯HTML
  • 一切顺利后,使用limitTo所以我可以从一开始就将项目限制为3,单击按钮后,我希望其余部分加载。

我请求帮助,这是我来的。

示例代码,因为SO需要它:

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

app.controller('mainController', function($scope, $http) {

$http({
    method: 'GET',
    url: 'notifications.json'
}).success(function(){
    console.log('success');
}).error(function(){
    console.log('error');
});

$scope.loadmore = true;
});

这是Plunker

提前谢谢你!

7 个答案:

答案 0 :(得分:1)

你的傻瓜有几个错误。

首先,index.html中的ng-app应为notifyApp,因为这是您在script.js - var app = angular.module('notifyApp', []);

中设置的内容

其次:您必须在成功函数中将通知分配给$scope.notifications

$http({
    method: 'GET',
    url: 'notifications.json'
}).then(function(res){
    $scope.notifications = res;
});

之后你应该已经看到了前3个元素。

您需要的最后一件事是从加载更多按钮的notifications = !notifications attr中删除ng-click

修改了Plunker here

答案 1 :(得分:1)

设置视图并使用ng-repeat。

您希望将通知存储在某处(可能是数组),然后在标记中的html文件中使用ng-repeat =“yourArray中的数据”(例如div)。如果要显示特定通知,则可以对其应用过滤器。在您的情况下,您希望最初显示3,然后在单击按钮时移动到其余部分。您可以创建一个单独的数组来存储前3个通知,另一个包含整个数组,并在标记中使用ng-if来显示结果。

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

myApp.controller('notificationController', ['$scope',
  function($scope) {
    $scope.buttonNotClicked = true;

    $scope.fullArray = [item1, item2, item3, item4, item5];
    $scope.partialArray = [fullArray[0], fullArray[1], fullArray[2]];


    function onButtonClick() {
      $scope.buttonNotClicked = false;
    }
  }
]);
<div ng-if="buttonNotClicked">
  <div ng-repeat="data in partialArray"></div>
</div>

<div ng-if="!buttonNotClicked">
  <div ng-repeat="data in fullArray"></div>
</div>

How to use parameters within the filter in AngularJS?

答案 2 :(得分:1)

所以第一步是在成功回调中你应该保存然后在你的范围内的某处返回数据,例如:

.success(function (data) {

   $scope.myList = data;

   $scope.myListLimit = 3; // lets also set a limit for our list
}

然后,您可以将视图编写为指向ng-controller指令的元素的后代:

<div ng-controller="mainController">
  <ul ng-repeat="item in myList | limitTo: myListLimit">
    <li>{{item}}</li>
  </ul>
  <button type="button" ng-show="anyResultsPending()" ng-click="showMoreResults()">Show more results</button>
</div>

之后,您的列表应显示3个结果,并且为了能够显示更多用户交互的结果,我们在控制器上创建一个新方法:

$scope.showMoreResults = function () {

   $scope.myListLimit += 3;
}

// this is to hide the "show more results" button after the all items was shown
$scope.anyResultsPending = function () {

   return $scope.myList && $scope.myListLimit < $scope.myList.length; 
}

答案 3 :(得分:1)

此外,正如AngularJS : Insert HTML into view中所述, 当使用JSON中包含的HTML时,您需要进行Sanitize。使用此模块:

<script src="bower_components/angular-sanitize/angular-sanitize.js"></script>

在你的JS中,我很惊讶,它似乎就像添加一个依赖一样简单:

  var ricksiteControllers = angular.module('ricksiteControllers', ["ngSanitize"]);

  ricksiteControllers.controller('PagesCtrl', ['$scope', 'Page',
          function($scope, Page) {
              $scope.pages = Page.query();
  }]);

我的services.js有角度资源代码:

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

ricksiteServices.factory('Page', ['$resource',
  function($resource){
    return $resource('pages/:pageId.json', {}, {
      query: {method:'GET', params:{pageId:'pages'}, isArray:true}
    });
  }]);
// actually, the pageID parameter has only one value, only the default 'pages' is used.

答案 4 :(得分:1)

这是一个解决方案,可以完成其他一些答案所没有的解决方案:

  • 动画
  • 使用角度工厂直接从JSON加载对象并承诺
  • 限制3项目,并在点击按钮上加载其余项目

JavaScript的:

(function () {
    "use strict";

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

    module.factory('NotificationsService', ['$http', function ($http) {
        return {
            fetch: function () {
                return $http.get('notifications.json').then(function (response) {
                    return response.data
                });
            }
        };
    }]);

    module.controller('Controller', ['$scope', '$filter', 'NotificationsService', function ($scope, $filter, NotificationsService) {
        $scope.notifications = [];
        $scope.limit = 3;
        $scope.allLoaded = false;

        NotificationsService.fetch().then(function (data) {
            $scope.notifications = data;
        });

        $scope.loadAll = function () {
            $scope.limit = $scope.notifications.length;
            $scope.allLoaded = true;
        };
    }]);
})();

HTML / CSS

<!doctype html>
<html ng-app="app">

<head>
    <title>ng-limit</title>

    <style>
        .my-repeat-animation.ng-enter,
        .my-repeat-animation.ng-leave,
        .my-repeat-animation.ng-move {
            -webkit-transition: 0.5s linear all;
            transition: 0.5s linear all;
            position: relative;
        }

        .my-repeat-animation.ng-enter {
            top: -20px;
            opacity: 0;
        }

        .my-repeat-animation.ng-enter.ng-enter-active {
            top: 0;
            opacity: 1;
        }

        .my-repeat-animation.ng-leave {
            top: 0;
            opacity: 1;
        }

        .my-repeat-animation.ng-leave.ng-leave-active {
            top: -20px;
            opacity: 0;
        }

        .my-repeat-animation.ng-move {
            opacity: 0.5;
        }

        .my-repeat-animation.ng-move.ng-move-active {
            opacity: 1;
        }
    </style>

    <script src="node_modules/angular/angular.js"></script>
    <script src="node_modules/angular-animate/angular-animate.js"></script>
    <script src="app.js"></script>
</head>

<body ng-controller="Controller">
    <button ng-show="!allLoaded" ng-click="loadAll()">Load all</button>
    <div ng-repeat="notification in notifications | limitTo:limit" class="my-repeat-animation">
        <div>
            <h4>Notification: {{$index+1}}</h4>
            <div>
                Avatar: {{notification.avatar}}
            </div>
            <div>
                Type: {{notification.type}}
            </div>
            <div>
                Name: {{notification.userName}}
            </div>
            <div>
                Action: {{notification.userAction}}
            </div>
            <div>
                Target: {{notification.targetObject}}
            </div>
        </div>
    </div>
</body>

</html>

答案 5 :(得分:0)

我有一个解决方案。在你的plnkr中尝试一下。

请注意我是如何硬编码$scope.notifications的。您需要检索实际数据 - 无法弄清楚如何在plnkr中执行此操作。当您检索JSON时,您必须信任这样的数据:

var app = angular.module('notifications', []);
app.controller('mainController', function($scope, $http, $sce) {
   $http({
        method: 'GET',
        url: 'notifications.json'
    }).success(function(data){
        console.log('success');
        $scope.notifications = data;
        for (var i=0; i<$scope.notifications.length; i++){
             $scope.notifications[i].userAction = $sce.trustAsHtml($scope.notifications[i].userAction)
        }
    }).error(function(data){
        console.log('error');
    });
    $scope.myLimit = 3;

    $scope.loadmore = true;
});

编辑,因为可能有解释。以下是我所做的更改:

  • Angular Module有一个错误(错误的名字)所以我改变了JS的第一行。
  • 必须在JS中声明
  • $scope.notifications
  • 添加了$ scope.myLimit,以便我们可以修改limitTo
  • 的此变量
  • 在ng-click中,已移除notifications = !notifications,添加了myLimit = notifications.length,以便显示所有结果。
  • 最后,添加了ng-bind-html而不是{{notification.userAction}},因此可以将其显示为HTML。

<强> JS:

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

app.controller('mainController', function($scope, $http) {

$http({
    method: 'GET',
    url: 'notifications.json'
}).success(function(){
    console.log('success');
}).error(function(){
    console.log('error');
});

$scope.notifications = [
{
    "avatar" : "images/otherUser.png",
    "type" : "",
    "userName" : "Ivana Stankova",
    "userAction" : "<span class=\"heart\">&#10084;</span>&nbsp;your photo",
    "targetObject" : "images/targetPhoto.jpg"
},
{
    "avatar" : "images/otherUser2.png",
    "type" : "",
    "userName" : "Ivana Stankova",
    "userAction" : "<span class=\"heart\">&#10084;</span>&nbsp;your photo",
    "targetObject" : "images/targetPhoto.jpg"
},
{
    "avatar" : "images/otherUser4.png",
    "type" : "checkedIn",
    "userName" : "Dave Peters",
    "userAction" : "Checked in<br/><a href=\"#\">962 Grant Street Victoria</a>",
    "targetObject" : "images/place.jpg"
},
{
    "avatar" : "images/otherUser4.png",
    "type" : "commented",
    "userName" : "Dave Peters",
    "userAction" : "Commented on <a href=\"#\">your post</a><p>Hey guys,&nbsp8 o’clock? Let’s get some food first? How<br/>about that fancy restaurant we wanted to try for...</p>",
    "targetObject" : "images/targetPhoto.jpg"
},
{
    "avatar" : "images/otherUser.png",
    "type" : "",
    "userName" : "Ivana Stankova",
    "userAction" : "<span class=\"heart\">&#10084;</span>&nbsp;your photo",
    "targetObject" : "images/targetPhoto.jpg"
},
{
    "avatar" : "images/otherUser.png",
    "type" : "",
    "userName" : "Ivana Stankova",
    "userAction" : "<span class=\"heart\">&#10084;</span>&nbsp;your photo",
    "targetObject" : "images/targetPhoto.jpg"
},
{
    "avatar" : "images/otherUser4.png",
    "type" : "",
    "userName" : "Dave Peters",
    "userAction" : "<a href=\"#\">Made a new post.</a>",
    "targetObject" : "images/targetPhoto.jpg"
},
{
    "avatar" : "images/otherUser.png",
    "type" : "",
    "userName" : "Ivana Stankova",
    "userAction" : "Started following you.",
    "targetObject" : ""
},
{
    "avatar" : "images/fivePeople.png",
    "type" : "",
    "userName" : "",
    "userAction" : "Five people Started following You.",
    "targetObject" : ""
}
]

$scope.myLimit = 3;

    $scope.loadmore = true;
});

<强>的index.html

<!DOCTYPE html>
<html lang="en" ng-app="notifications">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>App</title>
    <link rel="stylesheet" href="style.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
    <script src="script.js"></script>
</head>
<body class="container" ng-controller="mainController">
    <header>
        <a id="logo" href="www.google.com"><img src="images/logo.png" alt="logo"></a>
        <nav id="menu">
            <ul>
                <li><a href="#"><img src="images/bell.png" alt="bell icon"></a></li>
                <li>
                    <a href="#">
                        <img src="images/message.png" alt="message icon">
                        <div id="nCount">22</div>
                    </a>
                </li>
                <li><a href="#"><img src="images/profilePic.png" alt="girl profile pic"></a></li>
            </ul>
        </nav>
    </header>
    <main>
        <div class="wrapper">
            <div id="list">
                <h1>My notifications</h1>
                <ul id="mainList" ng-show="notifications" class="slideInDown" ng-init="limit = myLimit">
                    <li ng-repeat="notification in notifications | limitTo: limit">
                        <figure>
                            <img src="{{notification.avatar}}" alt="other user photo">
                        </figure>

                        <div class="infoLine {{notification.type}}">
                            <a class="userName" href="#">{{notification.userName}}</a>
                            &nbsp;<span ng-bind-html="notification.userAction"></span>
                        </div>

                        <div class="whenWhat">
                            <span>
                                <img src="images/clock.png" alt="clock illustration">
                                2m
                            </span>
                            <img src="{{notification.targetObject}}" alt="photo">
                        </div>
                    </li>
                </ul>
            </div>
            <a id="loadMore" href="#" ng-show="loadmore" ng-click=" loadmore = false ; limit = notifications.length; myLimit = notifications.length" ng-class="{ active: notifications }" >Load More</a>
        </div>
    </main>
</body>
</html>

答案 6 :(得分:0)

首先,您应该使用then() promisse代替success()error()。这是应该使用promisses的当前方式。

您可以在ng-repeat属性中使用'limitTo = val'限制nrRepeat循环。

我制作了一个片段,向您展示解决问题的方法:

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

myApp.controller('myAppController', ['$scope', function($scope){
  $scope.defaultLimit = 3; // the default limit
  $scope.list = ['item 1', 'item 2', 'item 3', 'item 4', 'item 5', 'item 6', 'item 7'];
  $scope.showAll = function(){
    $scope.defaultLimit = $scope.list.length; // show all reccords
  }  
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp">
  <div ng-controller="myAppController">
    <ul>
      <li ng-repeat="item in list | limitTo:defaultLimit">{{item}}</li>
    </ul>
    <button ng-click="showAll()" type="button">Show all</button>
  </div>
</div>