【问题标题】:ngInit not working properly with AngularJS and DjangongInit 无法与 AngularJS 和 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 使用相同的值在表中显示时,它会在两行中显示相同的值,这就是问题所在。 请帮忙。

【问题讨论】:

  • 控制台是否显示任何内容
  • 不。它什么都不显示
  • 是的,它正在按预期更新。即
    ...

标签: javascript angularjs django django-templates 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。后者是不可维护的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-20
  • 2020-10-25
  • 1970-01-01
  • 2017-12-14
相关资源
最近更新 更多