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

Cod*_*Med 5 javascript angularjs

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

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

我已经开发了部分实现此功能的代码,并将其发布到plnkr上。(感谢@shakir获得此plnkr来重新创建问题。)我还包括以下代码。

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

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

1.)someclass.prop1可以在视图中打印其值(在下面的代码中有效),并且

2.)ng-submitof confirmForm可以直接调用someclass.method1作为处理程序,从而最小化其中的代码someroute.js(这种情况在下面的代码中发生,但是在someclass.somemethod1()运行时未定义应包含表单数据的对象)


plnkr代码:


这是plnkr,其中包含对的服务调用@JoaozitoPolo。当前版本可以someclass.method1()从视图中调用,但是表单数据未传递到函数中。因此,我们需要弄清楚如何将表单数据传递到函数中。


此处显示的代码也:


的代码(在我的devbox)连接的属性和方法someview.htmlsomeclass.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;
            }
        );
    }
};

}]);
Run Code Online (Sandbox Code Playgroud)

这是以下代码someroute.js

angular
.module('someroute', ['someclass'])
.controller('someroute', function($scope, someclass) {

    $scope.someclass = someclass;

});
Run Code Online (Sandbox Code Playgroud)

这里是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>
Run Code Online (Sandbox Code Playgroud)

这是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>
Run Code Online (Sandbox Code Playgroud)

为了完整起见,我包括someroute_first.html,它很简单:

<h3>Showing first! </h3>
Run Code Online (Sandbox Code Playgroud)

someroute_second.html,就像:

<h3>Showing second! </h3>
Run Code Online (Sandbox Code Playgroud)

该应用程序的主要控制器是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';

            }
    )
Run Code Online (Sandbox Code Playgroud)

为了完整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>
Run Code Online (Sandbox Code Playgroud)

同样,上述所有代码都包含在此plnkr上再现问题所需的最少代码摘录中那么,需要对1.)使plnkr正常工作和2.)获得要传递到调用中的表单数据进行哪些特定更改someclass.method1()

Joa*_*olo 1

我看你的笨蛋更新了。出色的。

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

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