我是AngularJS的新手,并尝试使用该框架重做我之前应用程序的一些工作。我正在尝试在我的应用程序(AngularJS v1.6.6)中创建一个消息框服务,模块调用该服务以在UI中显示弹出窗口。
我似乎无法弄清楚如何将服务的变量绑定到UI本身。我已经尝试在控制器中创建一个本地'MessageBox'变量并引用它的内容,以及简单地调用注入的变量而没有运气。有什么方法可以通过服务实现这一目标吗?我在考虑一个全局变量,但我已经看到了反对这一点的建议。
服务似乎是最好的路线,但我愿意接受任何更有意义的建议。其他模块需要显示自己的错误或成功消息,所以我认为创建一种标准的方法来处理它会更容易。
我的代码如下:
消息box.template.html
<div id="message" ng-show="$ctrl.MessageBox.display" style="background-color: white; border: 1px solid black; margin: 5px; float: right; top: 60px; right: 2%; padding: 5px; position: fixed; z-index: 100;">
<img id="message-image" height="30" width="30" alt="{{ $ctrl.MessageBox.Image.alt }}" ng-src="{{ $ctrl.MessageBox.Image.source }}" /> <span id="message-text">{{ $ctrl.MessageBox.text }}</span>
</div>
消息box.module.js
angular.module("components.message-box", ["components"])
.controller("MessageBoxController", ["$scope", "MessageBox", function MessageBoxController($scope, MessageBox) {
}]);
消息box.component.js
/**
* message-box.component.js
* Contains the 'message-box' component
*/
angular.module("components.message-box")
.component("messageBox", {
templateUrl: "/Scripts/cop/components/message-box/message-box.template.html",
controller: "MessageBoxController"
});
消息box.service.js
/**
* message-box.service.js
* Defines the 'message-box' service
*/
angular.module("components.message-box")
.service("MessageBox", function () {
var self = this;
self.display = false;
self.Image = {
alt: null,
source: null
};
self.text = null;
self.timeout = null;
/**
* Hides the displayed message
* @public
*/
self.hideMessage = function () {
self.display = false;
self.timeout = null;
self.Image.alt = null;
self.Image.source = null;
self.text = null;
};
/**
* Displays the provided message to the user
* @public
* @param {string} text Message text
* @param {Object} Image Image display data
* @param {number} [hideTimeoutMs=null] Number of miliseconds to wait before hiding the message
*/
self.showMessage = function (text, Image, hideTimeoutMs) {
self.text = text;
self.Image.alt = Image.alt;
self.Image.source = Image.src;
self.display = true;
// Cancel timer for current timeout if it exists
if (self.timeout !== null) {
self.timeout = null;
}
// Set a new timeout if specified
if (hideTimeoutMs !== undefined) {
self.timeout = setTimeout(self.hideMessage, hideTimeoutMs);
}
};
});
以下是尝试调用服务的示例:
visual.module.js
angular.module("core.visual", [
"ngRoute",
"core.visual.settings"
])
.controller("VisualController", ["$routeParams", "$scope", "MessageBox",
function VisualController($routeParams, $scope, MessageBox) {
var self = this;
self.MessageBox = MessageBox;
self.MessageBox.showMessage("This is a message", "/Content/Images/loading.png", "Loading", 10000);
}
]);
我也尝试过不使用MessageBox作为本地控制器变量而没有成功 - 这只是我最近的尝试。
我是否在正确的轨道上?这甚至可能吗?
答案 0 :(得分:0)
我发现了this问题,这有助于我找到答案。
以下是我对MessageBox服务所做的更改。我能够在不改变服务功能调用方式的情况下完成所有工作。
<强>消息box.service.js 强>
/**
* message-box.service.js
* Defines the 'message-box' service
*/
angular.module("components.message-box")
.factory("MessageBox", ["$rootScope", "$timeout", function ($rootScope, $timeout) {
var self = {};
// Declare the Message variables
self.display = false;
self.imageSrc = null;
self.text = null;
self.timeout = null;
/**
* Hides the displayed message
* @public
*/
self.hideMessage = function () {
// Nullify all properties
self.display = false;
self.imageSrc = null;
self.text = null;
self.timeout = null;
};
/**
* Displays the provided message to the user
* @public
* @param {string} text Message text
* @param {Object} imageSrc Image source location
* @param {number} [hideTimeoutMs=null] Number of miliseconds to wait before hiding the message
*/
self.showMessage = function (text, imageSrc, hideTimeoutMs) {
self.text = text;
self.imageSrc = imageSrc;
self.display = true;
// Set a new timeout if specified
if (hideTimeoutMs !== undefined) {
self.timeout = hideTimeoutMs;
}
else {
self.timeout = null;
}
// Broadcast changes
// Use a timeout so messages don't fail before controller instantiation
$timeout(function () { $rootScope.$broadcast("message:updated", self); });
};
return self;
}]);
&#13;
最大的变化是不在这里处理超时而是保持值;该服务现在在对消息进行更改时进行广播,并由以下控制器处理。
我仍然使用hideMessage()清除局部变量以保持一致性。我还删除了&#39; alt&#39;属性,因为我无法弄清楚如何让Angular管理该值(使用{{}}似乎无法正常工作)。
此处使用的$ timeout会在广播更改之前稍微延迟。在某些情况下,如果在控制器中立即调用showMessage()(在完全构造之前),则不会显示该消息,因此这将修复该消息。在较大的应用程序中,这可能还不够,但这相对较小。
大部分更改都在组件的控制器中:
<强>消息box.module.js 强>
/**
* message-box.module.js
* Defines the 'components.message-box' module
*/
angular.module("components.message-box", ["components"])
.controller("MessageBoxController", ["$scope", "MessageBox", function MessageBoxController($scope, MessageBox) {
// Listen for message changes
$scope.$on("message:updated", function (evt, data) {
// Update global message variable
$scope.$apply(function () {
$scope.Message = data;
});
// Check for a timeout
if (data.timeout !== null) {
setTimeout(function () {
$scope.$apply(function () {
data.hideMessage();
});
}, data.timeout);
}
});
}]);
&#13;
控制器现在侦听消息更新事件。当发生这种情况时,控制器使用$ apply用新消息替换范围值,以便UI也更新。同样,它现在处理消息消失的超时值(如果适用),并且还使用$ apply,因为UI仍然需要知道何时不再显示消息。
<强>消息box.template.html 强>
<div id="message" ng-show="Message.display" style="background-color: white; border: 1px solid black; margin: 5px; float: right; top: 60px; right: 2%; padding: 5px; position: fixed; z-index: 100;">
<img id="message-image" height="30" width="30" alt="Information" ng-src="{{ Message.imageSrc }}" /> <span id="message-text" ng-bind="Message.text"></span>
</div>
&#13;
( message-box.component.js 未发生变化)
希望这可以帮助处于类似情况的人。这个解决方案对我有用,但如果有更好的方法来解决这个问题,请告诉我。