使用 Angular ng-show 和 ajax 请求获取详细信息

Using Angular ng-show with ajax request to get details

我是 angular 的新手,我正在尝试整理一个通知列表。真的很基本。显示通知的摘要列表。然后用户可以单击通知,然后显示通知的详细信息。这个 JSFiddle 显示了我放在一起的内容。

var notificaitonsApp = angular.module('notificationsApp', []);
var notificationListCtrl = notificaitonsApp.controller('NotificationListCtrl', [
        '$scope', '$http',
        function($scope, $http) {

            $scope.notifications = getNotifications();
            
            function getNotifications() {
                var Data = [{
                    "id": "1",
                    "primary_line": "Missing Timesheet Entry",
                    "secondary_line": "Jan 28th",
                    "summary_item": false,
                    "message": "A notification description. Do something here. Blah, blah, blah",         
                    "actions": [{
                        "type": "Navigation",
                        "url": "http://somedomain.cm/app/234",
                        "url_text": "Update"
                        },{
                        "type": "Post",
                        "url": "http://somedomain.com/app/api/v1/234",
                        "url_text": "Approve"
                        }]
                },{
                    "id": "2",
                    "primary_line": "Purchase Reqest Approval Needed",
                    "secondary_line": "Account 333445, Requested by James",
                    "summary_item": false,
                    "message": "A different notification message. Take action now.",
                    "actions": [{
                        "type": "Navigation",
                        "url": "http://somedomain.com/pr/requisitions/434",
                        "url_text": "Edit"
                    },{
                        "type": "Post",
                        "url": "http://somedomain.com/pr/api/v1/requisitions/434",
                        "url_text": "Approve"
                    }]
                }, {
                    "id": "3",
                    "primary_line": "Multiple Items Need Your Attention",
                    "secondary_line": "",
                    "summary_item": true,
                    "message": ""
                }, {
                    "id": "4",
                    "primary_line": "Your Time Off Request was Approved",
                    "secondary_line": "Jan 28th",
                    "summary_item": false,
                    "message": "Yet another notification message. You need to do something.",
                    "actions": [{
                        "type": "Navigation",
                        "url": "http://somedomain.com/pr/requisitions/434",
                        "url_text": "Edit"
                    }]
                }];
            
                return Data;
            }
            
            $scope.showNotificationDetail = function(notificationId) {
                $('div#' + notificationId).toggle(300);
            }
            
            $scope.doNotificationPost = function(postUrl) {
                console.log("POST: " + postUrl);
            }
            
            $scope.doNotificationNavigation = function(navigationUrl) {
                console.log("Navigation: " + navigationUrl);
            }
        }]);
body {
    background-color: #F8F6ED
}
ul
{
    margin-top: 0;
    margin-bottom: 2px;
    padding: 0;
}
li
{
    font-family: Georgia;
    background-color: #EFE7D5;
    list-style: none;
    margin-left: 0px;
}
a
{    
    text-decoration: none;
}
#primary
{
    padding: 1% 2% 0 2%;
    font-size: 18px;
    color: #978778;
}
#secondary
{
    padding: 0 2% 1% 2%;
    font-size: 14px;
    color: #5B4F48;
}

div.notification_hidden {
    display: none;
}

.inline {
    display: inline-block;
    vertical-align: middle;
}

.submit {
    margin-left: auto;
    margin-right; auto;
    text-align: right;    
}

button.notification_button {
   width: 85px; 
   height: 30px;
}

button.action_button {
    background-color: #cf6b28;
    border: 0 none;
    border-radius: 4px;
    color: #fff;
    cursor: pointer;
    font-weight: bold; 
    padding: 6px 15px;
}

button.modify-button {
    background-color: #978778;
    color: #fff;
    cursor: pointer;
    border: 0 none;
    border-radius: 4px;
    font-weight: bold;
    padding: 6px; 15px;
}
<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-app="notificationsApp">
    <div ng-controller="NotificationListCtrl">
        <div>
            Notifications
        </div>
        <div id="notifications">
            <div ng-if="notifications.length == 0">
                No Notifications
            </div>
            <ul ng-if="notifications.length > 0" ng-repeat="notification in notifications">
                <a ng-if="notification.summary_item == false" ng-href="#here" ng-click="showNotificationDetail(notification.id)">
                    <li id="primary">{{notification.primary_line}}</li>
                    <li id="secondary">{{notification.secondary_line}}</li>
                </a>
                <a ng-if="notification.summary_item == true" href="{{notification.summary_url}}" id="{{notification.id}}">
                    <li id="primary">{{notification.primary_line}}</li>
                </a>
                <div class="notification_hidden" id="{{notification.id}}">
                    <div class="inline-block">
                        <div class="inline" id="primary_line">
                            {{notification.primary_line}}
                        </div>
                        <div class="inline" style="float: right">
                            <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAKCAYAAABi8KSDAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC41ZYUyZQAAAH1JREFUKFN1kEsKwCAMRL3/4Vzorq2fiJsW75A6UkVTFB46SYYkqlJuTslzPWpHzzfh/cExXi0gQTyEsz6/YoCANEDPsZEAMPSWuKV5KQYxOrZWV5Orcs0tAhA5NkYz0X/pRaBtHwOm7RhyGSCX3hZ2ZoPKmcY/7sD8pTz8AhpjX7xHPMGHAAAAAElFTkSuQmCC" alt="Close"/>
                        </div>
                    </div>  
                    <div id="message_container">
                        {{notification.message}}
                    </div>
                    <div class="submit">
                        <div class="inline" ng-repeat="action in notification.actions">
                            <div class="inline" ng-if="action.type == 'Navigation'">
                                <button class="notification_button modify-button" ng-click="doNotificationNavigation(action.url)">{{action.url_text}}</button>
                            </div>
                            <div class="inline" ng-if="action.type == 'Post'">
                                <button class="notification_button action_button" ng-click="doNotificationPost(action.url)" type="submit">{{action.url_text}}</button>
                            </div>
                        </div>
                    </div>
                </div>
            </ul>
        </div>
    </div>  
</div>  

虽然这种方法有效,但我宁愿不加载所有通知及其详细信息和操作,只是为了显示摘要列表。我想显示摘要列表,然后当用户单击通知时,使用 ajax 请求获取通知详细信息,然后显示详细信息。

我不确定如何处理这个问题。我有一个模糊的想法,我需要一个指令和一个模板,但不知道如何切换通知详细信息模板的显示。我希望有一个更简单的解决方案。有人能指出我正确的方向吗?

我已经为你的问题组装了一个解决方案,它使用了大量的范围操作和一般范围的工作(我看到你不太熟悉 angular 所以我认为这可能对你有帮助了解有关 angular 范围的更多信息)。

首先你可以在 this plnkr 中找到我的代码。这里:

Index.html

<!DOCTYPE html>
<html>

  <head>
    <script data-require="angular.js@1.4.0-beta.3" data-semver="1.4.0-beta.3" src="https://code.angularjs.org/1.4.0-beta.3/angular.js"></script>
    <link href="style.css" rel="stylesheet" />
    <script src="script.js"></script>
  </head>

  <body>
<div ng-app="notificationsApp">
    <div ng-controller="NotificationListCtrl">
        <div>
            Notifications
        </div>
        <div id="notifications">
            <div ng-if="notifications.length == 0">
                No Notifications
            </div>
            <ul ng-if="notifications.length > 0" ng-repeat="notification in notifications">
                <a ng-if="notification.summary_item == false" ng-href="#here" ng-click="$parent.showdetail = !showdetail;loadData($parent);">
                    <li id="primary">{{notification.primary_line}}</li>
                    <li id="secondary">{{notification.secondary_line}}</li>
                </a>
                <a ng-if="notification.summary_item == true" href="{{notification.summary_url}}" id="{{notification.id}}">
                    <li id="primary">{{notification.primary_line}}</li>
                </a>
                <div id="{{notification.id}}" ng-show="showdetail">
                    <div class="inline-block">
                        <div class="inline" id="primary_line">
                            {{notification.primary_line}}
                        </div>
                        <div class="inline" style="float: right">
                            <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAKCAYAAABi8KSDAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC41ZYUyZQAAAH1JREFUKFN1kEsKwCAMRL3/4Vzorq2fiJsW75A6UkVTFB46SYYkqlJuTslzPWpHzzfh/cExXi0gQTyEsz6/YoCANEDPsZEAMPSWuKV5KQYxOrZWV5Orcs0tAhA5NkYz0X/pRaBtHwOm7RhyGSCX3hZ2ZoPKmcY/7sD8pTz8AhpjX7xHPMGHAAAAAElFTkSuQmCC" alt="Close"/>
                        </div>
                    </div>  
                    <div id="message_container">
                        {{notification.ressource.message}}
                    </div>
                    <div class="submit">
                        <div class="inline" ng-repeat="action in notification.ressource.actions">
                            <div class="inline" ng-if="action.type == 'Navigation'">
                                <button class="notification_button modify-button" ng-click="doNotificationNavigation(action.url)">{{action.url_text}}</button>
                            </div>
                            <div class="inline" ng-if="action.type == 'Post'">
                                <button class="notification_button action_button" ng-click="doNotificationPost(action.url)" type="submit">{{action.url_text}}</button>
                            </div>
                        </div>
                    </div>
                </div>
            </ul>
        </div>
    </div>  
</div>  
  </body>

</html>

还有我的剧本:

var notificaitonsApp = angular.module('notificationsApp', []);
var notificationListCtrl = notificaitonsApp.controller('NotificationListCtrl', [
        '$scope', '$http','$timeout',
        function($scope, $http, $timeout) {

            $scope.notifications = getNotifications();

            $scope.showdetail = false;

            function getNotifications() {
              var Data = [{
                "id": "1",
                "primary_line": "Missing Timesheet Entry",
                "secondary_line": "Jan 28th",
                "summary_item": false,
                "ressource":{
                    "message": "loading ..."
                }
                },{
                    "id": "2",
                    "primary_line": "Purchase Reqest Approval Needed",
                    "secondary_line": "Account 333445, Requested by James",
                    "summary_item": false,
                    "ressource":{
                        "message": "loading ..."
                    }
                }, {
                    "id": "3",
                    "primary_line": "Multiple Items Need Your Attention",
                    "secondary_line": "",
                    "summary_item": true,
                    "message": ""
                }, {
                    "id": "4",
                    "primary_line": "Your Time Off Request was Approved",
                    "secondary_line": "Jan 28th",
                    "summary_item": false,
                    "ressource":{
                        "message": "loading ...",
                        "actions":[]
                    }
                }];

                return Data;
            }


            $scope.loadData = function(parent) {
             $timeout(function(){},1000).then(function(result){
               var value = {
                    "message": "A notification description. Do something here. Blah, blah, blah",         
                    "actions": [{
                        "type": "Navigation",
                        "url": "http://somedomain.cm/app/234",
                        "url_text": "Update"
                        },{
                        "type": "Post",
                        "url": "http://somedomain.com/app/api/v1/234",
                        "url_text": "Approve"
                        }]
                };
                parent.notification.ressource = value;
             });
            };


            $scope.doNotificationNavigation = function(navigationUrl) {
                console.log("Navigation: " + navigationUrl);
            }
        }]);

我所做的简短描述:

我添加了一个范围变量 showdetail 用于隐藏和显示每个通知。要了解它的工作原理,您必须知道每个 ng-if 和 ng-repeat 都会创建一个新的隔离范围。这意味着 $parent.showdetail = !showdetail; 改变了父作用域的 showdetail 值,因为它在 ng-if 中使用,在 ng-repeat 中重复,我们实际上改变了 ng-repeat 的范围。

现在我们的 ng-show 更新了这个范围变量,因为我们的 ng-show 的范围也是我们 ng-repeat 在这个例子中的范围。应该只显示加载消息,因为只显示静态数据。

我们的 ng-click 中的 loadData($parent); 调用我们控制器中的一个函数,并将我们的父范围对象作为变量传递。在我们的控制器中,我们首先等待一个 scound 模仿 API 调用,然后我们改变给我们的对象。这意味着我们改变了 ng-repeat 的范围,并将从 API 获得的数据注入范围。 Angulars 数据绑定现在将确保我们的值得到更新和显示,而无需我们显式监视或轮询任何变量。

现在无需创建指令或使用任何其他监视即可显示正确的数据。我应该注意到,这工作得很好,但如果你想在你的代码中有一个更清晰的结构,你可以改用指令。

我希望这对你有所帮助并解决你的问题,如果有任何不清楚的地方,请告诉我。