繁体   English   中英

为什么AngularJS视图不能将数据发送到此可重用服务?

[英]Why can't AngularJS view send data to this re-usable service?

AngularJS应用程序需要重用多个自定义对象。 我担心创建难以维护的混乱冗余代码,因此我将可重用代码移动到可以在控制器中为每个视图简洁地注入的服务,然后直接从每个html视图调用,而不会使冗余控制器混乱码。

下图说明了如何someclass.js服务,以及为什么在一个地方尽可能多地隔离其代码很重要:

我已经开发了在我的devbox上部分完成此操作的代码 ,并且已将代码发布到plnkr (感谢@shakir让这个plnkr重新创建问题。)我还包括下面的代码。

虽然单击表单提交按钮确实会导致调用服务中表单的处理程序方法,但问题是应该包含表单数据的对象在应该处理表单数据的someclass.method1()方法中是未定义的。 需要对下面的代码进行哪些具体更改,以便可以在服务的表单处理方法中操作表单中用户提交的数据的值?

视图和服务(通过控制器)之间的通信的完整要求是:

1.) someclass.prop1可以在视图中打印其值(这适用于下面的代码),和

2.) confirmFormng-submit可以直接调用someclass.method1作为处理程序,从而最小化someroute.js中的代码(这在下面的代码中发生,但是在某些类中没有定义应该包含表单数据的对象someclass.somemethod1()正在运行)


plnkr代码:


这是pnkr@JoaozitoPolo建议的服务的调用。 当前版本能够从视图中调用someclass.method1() ,但表单数据不会传递给函数。 所以我们需要弄清楚如何将表单数据传递给函数。


代码在这里显示:


(在我的devbox上)将someview.html的属性和方法与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处理的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 ,我包括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>

同样,所有上述代码都包含在此plnkr中重现问题所需的最小代码摘录中 那么需要进行哪些具体的更改1.)让plnkr工作; 2.)获取表单数据以传递给someclass.method1()的调用?

我看起来你的plunker更新。 优秀的。

只有someclass.js上的问题...你需要在内部函数中使用“$ this”变量来访问正确的范围:

$http.post('/some-test-service', funcJSON).then(
    function(response) {
        $this.prop2 = response.data.content;
    }
);

表单提交功能是否正确?

我不确定我是否会让你们休息,但如果问题是将表单数据传递给someclass.method1,我会尝试这样的事情:

ng-submit="someclass.method1(confirmForm.$valid,someclass.resultphone)"

而不是这个:

ng-submit="someclass.method1(confirmForm.$valid)"

someclass.method1定义如下

this.method1 = function(isValid, resultphone) {...}

对?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM