【发布时间】:2023-03-16 17:38:02
【问题描述】:
AngularJS 应用程序需要重用多个自定义对象。我担心创建难以维护的杂乱、冗余代码,因此我将可重用代码移至一个服务,该服务可以为每个视图简明地注入到控制器中,然后直接从每个 html 视图调用,而不会使控制器变得混乱代码。
下图说明了服务someclass.js 将如何被重用,以及为什么将尽可能多的代码隔离在一个地方很重要:
我开发的代码可以在我的 devbox 上部分完成,我有 posted the code to a plnkr。 (感谢@shakir 让这个 plnkr 重新创建问题。)我还包括下面的代码。
虽然单击表单提交按钮确实会调用服务中的表单处理程序方法,但问题是应该包含表单数据的对象在应该处理表单数据的 someclass.method1() 方法中未定义. 需要对下面的代码进行哪些具体更改,以便可以在服务的表单处理方法中操作表单中用户提交的数据的值?
视图和服务之间(通过控制器)通信的完整要求是:
1.) someclass.prop1 可以在视图中打印其值(这在下面的代码中有效),并且
2.) confirmForm 的 ng-submit 可以直接调用 someclass.method1 作为处理程序,从而最小化 someroute.js 中的代码(这发生在下面的代码中,但是应该包含的对象someclass.somemethod1() 运行时未定义表单数据)
plnkr 代码:
这里是the plnkr 与@JoaozitoPolo 建议的服务的调用。当前版本能够从视图中调用someclass.method1(),但表单数据没有传递到函数中。所以我们需要弄清楚如何将表单数据传递给函数。
此处还显示代码:
(在我的devbox上)将someview.html的属性和方法与someclass.js连接起来的代码(但在函数调用期间不会将表单中的数据发送到someclass.js)如下:
这是someclass.js的代码:
angular
.module('someclass', ['ngCookies'])
.service('someclass', ['$rootScope', '$http', '$cookies', function($rootScope, $http, $cookies){
this.prop1 = $cookies.get('test1');
this.prop2 = 'nothing';
this.resultphone = {};
this.method1 = function(isValid, resultphone) {
if(isValid){
var funcJSON = resultphone;
funcJSON.wleadid = '1';//resultphone is undefined in debugger here
alert("just a filler to add breakpoint for debugger");
$http.post('/some-test-service', funcJSON).then(
function(response) {
prop2 = response.data.content;
}
);
}
};
}]);
这是someroute.js的代码:
angular
.module('someroute', ['someclass'])
.controller('someroute', function($scope, someclass) {
$scope.someclass = someclass;
});
这里是someroute.html:
someclass.prop1 is: {{someclass.prop1}} <br>
someclass.prop2 is: {{someclass.prop2}} <br>
<div ng-show="someclass.prop1!='yes'">
<h1>someclass prop1!</h1>
<div ng-include="'someroute_start.html'"></div>
</div>
<div ng-show="someclass.prop1=='yes'">
<div ng-show="someclass.prop2=='showfirst'">
<h1>Include start.</h1>
<div ng-include="'someroute_first.html'"></div>
</div>
<div ng-show="someclass.prop2=='showsecond'">
<h2>Include second.</h2>
<div ng-include="'someroute_second.html'"></div>
</div>
</div>
这里是someroute_start.html,里面包含了需要someclass.js处理的表单:
<form name="confirmForm" ng-submit="someclass.method1(confirmForm.$valid)" novalidate>
Enter some value:
<input type="text" name="phonenum1" ng-model="resultphone.phonenum1" required />
<button type="submit" ng-disabled="confirmForm.$invalid" >Submit</button>
</form>
为了完整起见,我包括someroute_first.html,很简单:
<h3>Showing first! </h3>
还有someroute_second.html,就这么简单:
<h3>Showing second! </h3>
应用程序的主控制器是hello.js,我将其包括在此处,以防部分解决方案包括初始化someclass:
angular
.module('hello', [ 'ngRoute', 'someclass', 'home', 'someroute', 'navigation' ])
.config(
function($routeProvider, $httpProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider.when('/', {
templateUrl : 'home.html',
controller : 'home'
})
.when('/someroute', {
templateUrl : 'someroute.html',
controller : 'someroute'
}).otherwise('/');
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
}
)
为了完整起见,index.html 按如下方式加载模块:
<!DOCTYPE html>
<html>
<head>
<script>document.write('<base href="' + document.location + '" />');</script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular-route.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.min.css"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" />
<link href="style.css" rel="stylesheet"/>
<style type="text/css">
[ng\:cloak], [ng-cloak], .ng-cloak { display: none !important; }
</style>
</head>
<body class="ng-cloak" ng-cloak="" ng-app="hello">
<div class="container" ng-controller="navigation">
<ul role="tablist" class="nav nav-pills">
<li ng-class="{active:tab('home')}">
<a href="#/">home</a>
</li>
<li ng-class="{active:tab('someroute')}">
<a href="#/someroute">some route</a>
</li>
</ul>
</div>
<div class="container" ng-view=""></div>
<script type="text/javascript" src="someclass.js"></script>
<script type="text/javascript" src="home.js"></script>
<script type="text/javascript" src="someroute.js"></script>
<script type="text/javascript" src="navigation.js"></script>
<script type="text/javascript" src="hello.js"></script>
</body>
</html>
同样,以上所有代码都包含在a bare minimum excerpt of code required to reproduce the problem at this plnkr 中。 那么需要对 1.) 使 plnkr 工作和 2.) 将表单数据传递到对 someclass.method1() 的调用进行哪些具体更改?
【问题讨论】:
-
<input type="text" name="phonenum1" ng-model="resultphone.phonenum1" required />应该是<input type="text" name="phonenum1" ng-model="someclass.resultphone.phonenum1" required /> -
@shakib 谢谢,但更改该行并没有解决问题。
resultphone和funcJSON在someclass.method1()中未定义,并且在 eclipse 调试器在该方法中给出funcJSON.wleadid = '1';行后程序简单地停止运行。也许如果我们能让 plnkr 工作,它可能更容易调试。在您的建议之后,在我的 Firefox 开发箱上运行的版本按照此评论中的描述工作。还有其他想法吗? -
添加了
ngCookies模块脚本引用并更改了someclass.js中的cookie 代码。运行 plunkr plnkr.co/edit/JInT1u1n79M6HNW7qtNZ -
@shakib 您还添加了
var $this = this;,这是解决方案的关键部分。
标签: javascript angularjs