angular:当输入改变+ .this / $ scope时更新视图

时间:2015-03-11 16:38:37

标签: javascript angularjs jsfiddle

我有几个问题似乎无法弄清楚。我试图用一个小提示来显示我的问题,但我似乎无法让它工作,虽然它在我的应用程序中工作。(https://jsfiddle.net/6dfyx2og/1/#&togetherjs=KxPTHsH0Pu)。值显示在屏幕上,可以通过输入框进行操作。但是现在$scope.booking.nights如果用户更改了值,则不会更新。 (在我的应用程序中,当用户填写到达日期和出发日期时,它会调用函数calNights给我们的夜晚数量)。

任何人都可以看到我的错误吗?

由于我无法使小提琴工作,我将在此处发布代码

控制器:

angular.module('squawsomeApp')
  .controller('BookingCtrl', function($scope){

    $scope.values = [1,2,3,4,5];

    // var self = this;

    function parseDate(str) {
      var mdy = str.split('/')
      return new Date(mdy[2], mdy[0]-1, mdy[1]);
    }

    function daydiff(first, second) {
      return (second-first)/(1000*60*60*24);
    }

    var calCheckIn = new Pikaday({
        field: document.getElementById('checkin'),
        format: 'MM/DD/YYYY',
        onSelect: function() {
          $scope.booking.checkin = null;
          $scope.booking.checkin = this.toString('MM/DD/YYYY');
          calNights();
        }
    });

    var calCheckOut = new Pikaday({
        field: document.getElementById('checkout'),
        minDate: $scope.checkin,
        format: 'DD/MM/YYYY',
        onSelect: function() {
          $scope.booking.checkout = this.toString('MM/DD/YYYY');
          calNights();
        }
    });

    var calNights = function(){
      console.log('outside')
      $scope.booking.nights = null;
      console.log($scope.booking.nights)
      if ($scope.booking.checkin && $scope.booking.checkout) {
        console.log('inside')
        $scope.booking.nights = daydiff(parseDate($scope.booking.checkin), parseDate($scope.booking.checkout));
        // return daydiff(parseDate(self.booking.checkin), parseDate(self.booking.checkout))
        console.log($scope.booking.nights)
      }
    };

    var calCost = function(){
      if ($scope.booking.nights < 7) {
        $scope.booking.cost = 145;
      } else if ($scope.booking.nights >= 7 && $scope.booking.nights <= 29){
        $scope.cost = 135;
      } else if ($scope.booking.nights >= 29){
        $scope.booking.cost = 120;
      }
    };

    $scope.booking = {
      checkin: null,
      checkout: null,
      guests: null,
      nights: null, //daydiff(parseDate(self.booking.checkin), parseDate(self.booking.checkout))
      cost: null,
      pretotal: this.nights * this.cost,
      tax: 0,
      total: this.pretotal + this.tax
    };

  });

HTML:

 <div controller="BookingCtrl">
    <form name="bookingForm" ng-submit="">
        <div class="form-fields">

            <label for="checkin">Check In</label>
            <input id="checkin" name="checkin" placeholder="dd-mm-yyyy" type="text" ng-model="booking.checkin">
            <label for="checkout">Check Out</label>
            <input id="checkout" name="checkout" placeholder="dd-mm-yyyy" type="text" ng-model="booking.checkout">
            <label for="guests">Guests</label>
            <select ng-model="booking.guests" ng-options="value for value in values"></select>

            <ul>
                <li>{{booking.checkin}}</li>
                <li>{{booking.checkout}}</li>
                <li>{{booking.nights}}</li>
                <li>{{booking.guests}}</li>
                <li>{{booking.cost}} x {{booking.nights}}</li>
                <li>Tax</li>
                <li>Total</li>
            </ul>

            <ul>
                <li>{{booking.pretotal}}CND</li>
                <li>{{tax}}CND</li>
                <li>{{booking.total}}</li>
            </ul>

            <input type="submit" value="Submit" ng-disabled="bookingForm.$invalid">

        </div>
    </form>
</div>

作为旁白我最初想在控制器中使用this / self语法而不是使用$ scope。这很好用,但我无法在视图中显示值。 (绑定到输入的那些会出现,但这只是由于数据绑定,它们不会显示初始值。如果有人可以解释为什么这是请告诉我。

即为什么控制器中没有显示视图中的值

var self = this;

self.booking = {
      checkin: null,
      checkout: null,
      guests:  null,
      nights: null, 
      cost: null,
      pretotal: this.nights * this.cost,
      tax: 0,
      total: this.pretotal + this.tax
    };

但是这样做了:

$scope.booking = {
  checkin: null,
  checkout: null,
  guests: null,
  nights: null, 
  cost: null,
  pretotal: this.nights * this.cost,
  tax: 0,
  total: this.pretotal + this.tax
};

2 个答案:

答案 0 :(得分:0)

范围对象($ scope)使控制器和视图能够相互通信。如果将属性放在 self 而不是scope对象上,则视图无法使用它们,因为它们是控制器本身的属性,而不是作用域对象。在视图中对输入元素进行数据绑定时,Angular会在其创建并传递给控制器​​的范围对象中查找绑定属性。如果它找不到它们,它将在范围对象中创建属性并将输入绑定到它们。另一方面,如果您具有在控制器中给出值的范围对象的属性,则Angular会将该属性绑定到您已绑定到该属性的数据输入。因此,输入将在页面上具有初始值,该值是控制器设置的值。

答案 1 :(得分:0)

您可以使用this / self语法 - 但您应该使用ControllerAs语法。

<div ng-controller="BookingCtrl as book">
  <p>{{ book.booking.checkin }}</p>
</div>

阅读文档中的所有内容:)

https://docs.angularjs.org/api/ng/directive/ngController