使用 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 数据绑定现在将确保我们的值得到更新和显示,而无需我们显式监视或轮询任何变量。
现在无需创建指令或使用任何其他监视即可显示正确的数据。我应该注意到,这工作得很好,但如果你想在你的代码中有一个更清晰的结构,你可以改用指令。
我希望这对你有所帮助并解决你的问题,如果有任何不清楚的地方,请告诉我。
我是 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 数据绑定现在将确保我们的值得到更新和显示,而无需我们显式监视或轮询任何变量。
现在无需创建指令或使用任何其他监视即可显示正确的数据。我应该注意到,这工作得很好,但如果你想在你的代码中有一个更清晰的结构,你可以改用指令。
我希望这对你有所帮助并解决你的问题,如果有任何不清楚的地方,请告诉我。