ngInit 无法与 AngularJS 和 Django 一起正常工作

Posted

技术标签:

【中文标题】ngInit 无法与 AngularJS 和 Django 一起正常工作【英文标题】:ngInit not working properly with AngularJS and Django 【发布时间】:2017-10-24 14:56:59 【问题描述】:

我在 view.py 中将元组列表从视图传递到模板,如下所示:

def index(request):
    page_index =  int(request.GET["page"])
    s_page = (page_offset*page_index) + 1
    e_page = (page_index + 1)*page_offset
    user_statuses = get_user_status()
    user_statuses.sort(key=lambda user_statuses: datetime.datetime.strptime(user_statuses[0], '%Y-%m-%d'),reverse=True)
    print user_statuses
    user_statuses = user_statuses[s_page : e_page+1]
    print user_statuses
    return render(request, 'view_status.html', 'lists': user_statuses,'next_page':page_index+1,'prev_page':page_index-1)

user_statuses 是元组列表。

下面是我的模板:

   <body>
      <div ng-app="appTable">
         <div ng-controller="Allocation">
            <h2><span>VIEW STATUS</span></h2>
            <a ng-href="/welcome_page/">Return to Welcome Page</a><br><br>  
            Select start date:
            <input type="text"
               datepicker
               ng-model="start_date" />
            <br>
            <br>
            Select end date:
            <input type="text"
               datepicker
               ng-model="end_date" />
            <br>
            <br>
            <button ng-click="Submit()"> Submit </button> 
            %verbatim%    error%endverbatim%
            %verbatim%    msg%endverbatim%
            <br>
            <table>
               <th bgcolor="#35a5f0">   
               <td bgcolor="#35a5f0">Date</td>
               <td bgcolor="#35a5f0">Project</td>
               <td bgcolor="#35a5f0">Release</td>
               <td bgcolor="#35a5f0">Feature</td>
               <td bgcolor="#35a5f0">Module name</td>
               <td bgcolor="#35a5f0">Hours spent</td>
               <td bgcolor="#35a5f0">Comment</td>
               </th>
               </thead>
               <tbody>
                  %for list in lists%
                  <tr>
                     list.0 list.1
                     <td><input type="checkbox" ng-model="data.isDelete"/></td>
                     <td>
                        <div ui-view  ng-init="data.date='list.0'" >
                           <input type="text"
                              datepicker
                              ng-model="data.date" />
                        </div>
                     </td>
                     <td>
                        <div ng-init="data.dept='list.1' " >
                           <input type="text" ng-model="data.dept" />
                        </div>
                     </td>
                     <td>
                        <select ng-model="data.release" ng-options="x for x in range">
                        </select>
                     </td>
                     <td>
                        <select ng-model="data.feature" ng-options="x for x in feature">
                        </select>
                     </td>
                     <td>
                        <input type = "text" ng-model = "data.modulename">
                     </td>
                     <td>
                        <select ng-model="data.hours" ng-options="x for x in hours">
                        </select>
                     </td>
                     <td>
                        <input type = "text" ng-model = "data.comment">
                     </td>
                  </tr>
                  % endfor %
               </tbody>
            </table>
            <a ng-href="/view_status/?page=prev_page">Previous</a>  
            <a ng-href="/view_status/?page=next_page">Next</a>  
         </div>
      </div>
   </body>

这是我的 AJ 脚本:

<script>
    var app = angular.module("appTable", []);

    app.controller("Allocation", function($scope, $http) 
        $scope.start_date = "2017-05-01";
        $scope.end_date = "2017-05-19";

        $scope.data = 
        $scope.hours = ["1", "2", "3"];
        $scope.range = ["1", "2", "3"];
        $scope.feature = ["UT", "FSDS", "Coding", "QA"];

        $scope.postData = function(s_date, e_date) 
            console.log('post called');
            var data = 
                s_date: s_date,
                e_date: e_date,


            ;
            console.log(data);
            $http.post('/view_status/', data).then(function(response) 
                if (response.data)
                    $scope.msg = "Data Submitted Successfully!";
            , function(response) 
                $scope.msg = "Service not Exists";
                $scope.statusval = response.status;
                $scope.statustext = response.statusText;
                $scope.headers = response.headers();
            );
        ;


    );

    app.directive("datepicker", function() 

        function link(scope, element, attrs, controller) 
            // CALL THE "datepicker()" METHOD USING THE "element" OBJECT.
            element.datepicker(
                onSelect: function(dt) 
                    scope.$apply(function() 
                        // UPDATE THE VIEW VALUE WITH THE SELECTED DATE.
                        controller.$setViewValue(dt);

                    );
                ,
                dateFormat: "yy-mm-dd" // SET THE FORMAT.
            );
        

        return 
            require: 'ngModel',
            link: link
        ;
    );
</script>

view.py 中字典 use​​r_statuses 的值如下:

[(u'2017-05-02', u'p2', u'1', u'UT', u'pqr', u'1', u'Add extra information'), (u'2017-05-01', u'p1', u'1', u'UT', u'abc', u'1', u'Add extra information')]

我的输出:

当我打印 list.0 和 list.1 时,您可以看到它显示了正确的输出。 但是,当我使用 ng-init 使用相同的值在表中显示时,它会在两行中显示相同的值,这就是问题所在。 请帮忙。

【问题讨论】:

控制台是否显示任何内容 不。它什么都不显示 是的,它正在按预期更新。即 ... 【参考方案1】:

我认为,你不应该在这里使用ng-init

这个指令可以被滥用来添加不必要的逻辑量 你的模板

这里发生的情况是,您在 javascript 中定义了一个名为 data 的局部变量,Angular 正在使用该变量来更新表单字段。然而问题在于,在您的 HTML 中,每一行都覆盖了 data 变量。所以他们最终都有相同的变量。

此外,将 Django 循环和 Angular 循环结合起来并不总是一个好主意,尤其是在使用 ng-init 时。

我认为您的正确方法是将 user_statuses 作为 ajax 响应传递并使用 ng-repeat 循环遍历它。

【讨论】:

ajax 和 ng-repeat 怎么办?你能多介绍一下吗? 这确实有点太宽泛了。我们需要克服 angularjs 非常陡峭的学习曲线来解释这一点。 好的。感谢您的回答。 django 和 angularjs 的结合是很困难的。我是这么认为的 并非如此。如果您使用 django rest 框架和 angular,这很容易。缺点是他们的学习曲线恰好非常陡峭【参考方案2】:

我可以在控制器中使用 %for% 来实现我的目标。这个循环将从列表中一一获取数据并附加到控制器中的列表“dataList”中。这个列表将被打印出来使用“ng-repeat”在 HTML 表的行中。下面是我的代码:

<html>
       <head>
          <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.0/themes/base/jquery-ui.css">
          <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
          <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
          <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
       </head>
       <style>
          h2 
          width: 100%; 
          text-align: center; 
          color:#35a5f0;
          line-height: 1em;
          margin: 10px 0 20px; 
          background-color:#35a5f0;
           
          h2 span  
          background:#fff; 
          padding:0 10px; 
          
          table, th , td 
          border: 1px solid grey;
          border-collapse: collapse;
          padding: 5px;
          
          table tr:nth-child(odd) 
          background-color: #f2f2f2;
          
          table tr:nth-child(even) 
          background-color: #ffffff;
          
       </style>
       <body>
          <div ng-app="appTable">
             <div ng-controller="Allocation">
                <h2><span>VIEW STATUS</span></h2>
                <a ng-href="/welcome_page/">Return to Welcome Page</a><br><br>  
                Select start date:
                <input type="text"
                   datepicker
                   ng-model="start_date" />
                <br>
                <br>
                Select end date:
                <input type="text"
                   datepicker
                   ng-model="end_date" />
                <br>
                <br>
                <button ng-click="Submit()"> Submit </button> 
                %verbatim%    error%endverbatim%
                %verbatim%    msg%endverbatim%
                <br>
                <span ng-init="add()"></span>
                <table>
                   <th bgcolor="#35a5f0">   
                   <td bgcolor="#35a5f0">Date</td>
                   <td bgcolor="#35a5f0">Project</td>
                   <td bgcolor="#35a5f0">Release</td>
                   <td bgcolor="#35a5f0">Feature</td>
                   <td bgcolor="#35a5f0">Module name</td>
                   <td bgcolor="#35a5f0">Hours spent</td>
                   <td bgcolor="#35a5f0">Comment</td>
                   </th>
                   <tr ng-repeat="data in dataList">
                      <td><input type="checkbox" ng-model="data.isDelete"/></td>
                      <td>
                         <input type="text"
                            datepicker
                            ng-model="data.date" />                 
                      </td>
                      <td><input type="text" ng-model="data.dept"/></td>
                      <td>
                         <select ng-model="data.release" ng-options="x for x in range">
                         </select>
                      </td>
                      <td>
                         <select ng-model="data.feature" ng-options="x for x in feature">
                         </select>
                      </td>
                      <td>
                         <input type = "text" ng-model = "data.modulename">
                      </td>
                      <td>
                         <select ng-model="data.hours" ng-options="x for x in hours">
                         </select>
                      </td>
                      <td>
                         <input type = "text" ng-model = "data.comment">
                      </td>
                   </tr>
                </table>
                <a ng-href="/view_status/?page=prev_page">Previous</a>  
                <a ng-href="/view_status/?page=next_page">Next</a>
             </div>
          </div>
       </body>
       <script>
 var app = angular.module("appTable", []);

          app.controller("Allocation", function($scope, $http) 
              $scope.start_date = "2017-05-01";
              $scope.end_date = "2017-05-15";

              $scope.data = 
              $scope.hours = ["1", "2", "3"];
              $scope.range = ["1", "2", "3"];
              $scope.feature = ["UT", "FSDS", "Coding", "QA"];
              $scope.dataList = [];
              $scope.displayList = [];

              $scope.update_data = function(dept) 
                  data.dept = dept;

              ;

              $scope.postData = function(s_date, e_date) 
                  console.log('post called');
                  var data = 
                      s_date: s_date,
                      e_date: e_date,


                  ;
                  console.log(data);
                  $http.post('/view_status/', data).then(function(response) 
                      if (response.data)
                          $scope.msg = "Data Submitted Successfully!";
                  , function(response) 
                      $scope.msg = "Service not Exists";
                      $scope.statusval = response.status;
                      $scope.statustext = response.statusText;
                      $scope.headers = response.headers();
                  );
              ;
              $scope.add = function() 
                   %
                      for list in lists %
                  
                  var data1 = ;

                  data1 = 
                      date: 'list.0',
                      dept: 'list.1',
                      release: 'list.2',
                      feature: 'list.3',
                      modulename: 'list.4',
                      hours: 'list.5',
                      comment: 'list.6'
                  ;
                  $scope.dataList.push(data1);

                   % endfor %
                  

              ;



          );

          app.directive("datepicker", function() 

              function link(scope, element, attrs, controller) 
                  // CALL THE "datepicker()" METHOD USING THE "element" OBJECT.
                  element.datepicker(
                      onSelect: function(dt) 
                          scope.$apply(function() 
                              // UPDATE THE VIEW VALUE WITH THE SELECTED DATE.
                              controller.$setViewValue(dt);

                          );
                      ,
                      dateFormat: "yy-mm-dd" // SET THE FORMAT.
                  );
              

              return 
                  require: 'ngModel',
                  link: link
              ;
          );
       </script>
    </html>

【讨论】:

很好的开始。最终计划将其更改为使用 JSON 而不是 django 生成的 javascript。后者是不可维护的

以上是关于ngInit 无法与 AngularJS 和 Django 一起正常工作的主要内容,如果未能解决你的问题,请参考以下文章

html 使用AngularJS MySearchboxDirective的示例。这演示了幻灯片http://slides.com/dj中演示的示例的一些修复

如何在 Angular 8 中实现 ngInit?

angularjs 在 ng-repeat 指令中预填充输入文本

为什么在构造函数中初始化的成员变量会在离子角的ngInit中未定义?

AngularJS 与 PHP:为啥我的应用程序无法保存输入文本发送的字符串?

angularjs 中的选项卡无法与 UI-Router 和 UI-bootstrap 一起正常工作