2016-01-25 27 views
1

我正嘗試使用AngularJS創建3-way綁定,以便可以動態更改表和localStorage中的值。我也使用jqueryUI dialog-window,我想更新值,然後將它保存到表和localStorage。在ng-model指令的幫助下,我正在填充對話框窗口的值。然後在accept按鈕我保存的值到本地存儲,並且表:使用AngularJS更新表中的值的最佳實踐

   data.name = $scope.dialogName; 
       data.author = $scope.dialogAuthor; 
       data.genre = $scope.dialogGenre; 
       data.price = $scope.dialogPrice; 

      self.book.name = $scope.dialogName; 
      self.book.author = $scope.dialogAuthor; 
      self.book.genre = $scope.dialogGenre; 
      self.book.price = $scope.dialogPrice; 

但我認爲這是一個壞主意(這個代碼不工作),並且必須有更好的方式來實現我的目標。謝謝。

在這個問題下面你可以找到codeSnippet,它可以讓你理解我的代碼。

books = [ 
 
    { 
 
    "name": "Javascript", 
 
    "author": "David Flanagan", 
 
    "genre": "learning", 
 
    "price": "100" 
 
    }, 
 
    { 
 
    "name": "PHP", 
 
    "author": "Luke Welling", 
 
    "genre": "learning", 
 
    "price": "120" 
 
    }, 
 
    { 
 
    "name": "Learning JavaScript Design Patterns", 
 
    "author": "Addy Osmani", 
 
    "genre": "learning", 
 
    "price": "400" 
 
    }, 
 
    { 
 
    "name": "Understanding ECMAScript 6", 
 
    "author": "Nicholas C. Zakas", 
 
    "genre": "learning", 
 
    "price": "204" 
 
    }, 
 
    { 
 
    "name": "Programming JavaScript Applications", 
 
    "author": "Eric Elliot", 
 
    "genre": "learning", 
 
    "price": "214" 
 
    }, 
 
    { 
 
    "name": "The C Programming Language", 
 
    "author": "Brian W. Kernighan", 
 
    "genre": "learning", 
 
    "price": "514" 
 
    }, 
 
    { 
 
    "name": "Programming Pearls", 
 
    "author": "Jon L. Bentley", 
 
    "genre": "learning", 
 
    "price": "114" 
 
    }, 
 
    { 
 
    "name": "Java Concurrency in Practice", 
 
    "author": "Brian Goetz", 
 
    "genre": "learning", 
 
    "price": "140" 
 
    } 
 
] 
 

 
var app = angular.module('app', []); 
 

 
app.controller('appCtrl', function ($scope, $http) { 
 
    $scope.title = "Angular Books List"; 
 
    $scope.books = books; 
 

 
    $scope.addNewTask = function() { 
 
     $scope.books = JSON.parse(localStorage['table']); 
 
     $scope.books.push({ 
 
      name: $scope.bookName, 
 
      author: $scope.bookAuthor, 
 
      genre: $scope.bookGenre, 
 
      price: $scope.bookPrice 
 
     }); 
 
     $scope.bookName = ""; 
 
     $scope.bookAuthor = ""; 
 
     $scope.bookGenre = ""; 
 
     $scope.bookPrice = ""; 
 
     localStorage.setItem("table", JSON.stringify($scope.books)); 
 

 
    }; 
 

 
    $scope.ShowConfirm = function() { 
 
     if (window.confirm("Are you sure?")) { 
 
      var local = JSON.parse(localStorage['table']); 
 
      for (var i = 0; i < local.length; i++) { 
 
       if (local[i].name == this.book.name) { 
 
        local.splice(i, 1); 
 
        $scope.books.splice(i, 1); 
 
        console.log(local); 
 
        console.log(i); 
 
        localStorage.setItem("table", JSON.stringify(local)); 
 
        break; 
 
       } 
 
      } 
 
     } else { 
 

 
     } 
 
    }; 
 

 
    $scope.enableEditor = function(book){ 
 
     var self = this, 
 
      data; 
 
     
 
     $scope.selectedBook = book; 
 
     $scope.dialogBook = angular.copy(book); 
 

 

 
     $('#editDisplay').dialog({ 
 
      modal: true, 
 
      resizable: false, 
 
      width: 400, 
 
      buttons: { 
 
       Accept: function() { 
 
        $(this).dialog("close"); 
 
        
 
        angular.copy($scope.dialogBook,$scope.selectedBook); 
 
        localStorage.setItem("table", JSON.stringify($scope.books)); 
 

 
       }, 
 
       Cancel: function() { 
 
        $(this).dialog("close"); 
 
       } 
 
      } 
 
     }); 
 

 
    }; 
 

 
    $scope.predicate = 'name'; 
 
    $scope.reverse = false; 
 
    $scope.order = function (predicate) { 
 
     $scope.reverse = ($scope.predicate === predicate) ? !$scope.reverse : false; 
 
     $scope.predicate = predicate; 
 
    }; 
 
});
.sortorder:after { 
 
    content: '\25b2'; 
 
} 
 
.sortorder.reverse:after { 
 
    content: '\25bc'; 
 
} 
 
.addBookInputs input { 
 
    display: inline-block; 
 
    width: 250px; 
 
} 
 
.addBookInputs { 
 
    margin-bottom: 40px; 
 
} 
 
input::-webkit-outer-spin-button, 
 
input::-webkit-inner-spin-button { 
 
    /* display: none; */ 
 
    -webkit-appearance: none; 
 
    margin: 0; 
 
}
<link href="https://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" rel="stylesheet"/> 
 
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<script src="https://code.jquery.com/ui/1.10.3/jquery-ui.js"></script> 
 
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> 
 

 
<body ng-app="app"> 
 

 

 
<div class="container" ng-controller="appCtrl"> 
 
    <div class="page-header"> 
 
     <h1> 
 
      {{title}} 
 
     </h1> 
 
    </div> 
 
    <div class="col-xs-12 col-sm-12 col-md-3 col-md-offset-9 col-lg-3 col-lg-offset-9"> 
 
     <input type="text" class="form-control" ng-model="searchField" placeholder="search book..."> 
 
     <br> 
 
     <br> 
 

 
    </div> 
 

 

 
    <div class="panel"> 
 
     <div class="addBookInputs"> 
 
      <input class="form-control" ng-model="bookName" placeholder="type name of the book"/> 
 
      <input class="form-control" ng-model="bookAuthor" placeholder="type author of the book"/> 
 
      <input class="form-control" ng-model="bookGenre" placeholder="type genre of the book"/> 
 
      <input class="form-control" ng-model="bookPrice" placeholder="type price of the book" type="number"/> 
 
      <span class=""> 
 
       <button class="btn btn-success" ng-click="addNewTask()">Add Book</button> 
 
      </span> 
 
     </div> 
 

 

 

 
     <table class="table table-hover table-bordered table-"> 
 
      <thead> 
 
      <tr> 
 
       <th> 
 
        <a href="" ng-click="order('name')">Book Name</a> 
 
        <span class="sortorder" ng-show="predicate === 'name'" ng-class="{reverse:reverse}"></span> 
 
       </th> 
 

 

 
       </th> 
 
       <th> 
 
        <a href="" ng-click="order('author')">Author</a> 
 
        <span class="sortorder" ng-show="predicate === 'author'" ng-class="{reverse:reverse}"></span> 
 
       </th> 
 
       <th> 
 
        <a href="" ng-click="order('genre') ">Genre</a> 
 
        <span class="sortorder" ng-show="predicate === 'genre'" ng-class="{reverse:reverse}"></span> 
 

 
       </th> 
 
       <th> 
 
        <a href="" ng-click="order('price')">Price</a> 
 
        <span class="sortorder" ng-show="predicate === 'price'" ng-class="{reverse:reverse}"></span> 
 
       </th> 
 

 

 
       <th>Delete?</th> 
 
      </tr> 
 
      </thead> 
 
      <tbody> 
 
      <tr ng-repeat="book in books | filter:searchField | orderBy:predicate:reverse" ng-hide="book.done"> 
 
       <td> 
 
        {{book.name}} 
 
       </td> 
 
       <td> 
 
        {{book.author}} 
 
       </td> 
 
       <td> 
 
        {{book.genre}} 
 
       </td> 
 
       <td> 
 
        {{book.price | currency}} 
 
       </td> 
 
       <td> 
 
        <button ng-click = "enableEditor(book)" class="btn btn-warning" > edit </button> 
 
        <button ng-click = "ShowConfirm()" class="btn btn-danger" > delete </button> 
 
       </td> 
 
       <!--<td>--> 
 
         <!--<span style="{{setStyle(book.done)}}">--> 
 
          <!--{{showText(book.done)}}--> 
 
         <!--</span>--> 
 
       <!--</td>--> 
 
      </tr> 
 
      </tbody> 
 
     </table> 
 

 
     <div id="editDisplay" class="form-horizontal" style="display:none" title="editor"> 
 
      <div class="control-group"> 
 
       <label class="control-label">id</label> 
 

 
       <div class="controls"> 
 
        <input class="input-block-level form-control" type="number" disabled> 
 
       </div> 
 
      </div> 
 

 
      <div class="control-group"> 
 
       <label class="control-label">name</label> 
 

 
       <div class="controls"> 
 
        <input class="input-block-level form-control" type="text" ng-model = "dialogBook.name"> 
 
       </div> 
 
      </div> 
 

 
      <div class="control-group"> 
 
       <label class="control-label">author</label> 
 

 
       <div class="controls"> 
 
        <input class="input-block-level form-control" type="text" ng-model = "dialogBook.author"> 
 
       </div> 
 
      </div> 
 

 
      <div class="control-group"> 
 
       <label class="control-label">genre</label> 
 

 
       <div class="controls"> 
 
        <input class="input-block-level form-control" type="text" ng-model="dialogBook.genre"> 
 
       </div> 
 
      </div> 
 
      <div class="control-group"> 
 
       <label class="control-label">price</label> 
 

 
       <div class="controls"> 
 
        <input class="input-block-level form-control" type="number" ng-model = "dialogBook.price"> 
 
       </div> 
 
      </div> 
 
     </div> 
 
    </div> 
 
</div> 
 

 

 
</body>

+0

*「這個代碼不起作用*」是不正確的問題說明。什麼或不工作?任何錯誤?提供更多詳情 – charlietfl

+1

不完全確定你想要達到的目標。你想消除重複的代碼?如果是這樣,請使用書籍對象而不是單獨的屬性。您是否試圖確保在每次更改時將書籍數組自動保存到本地存儲?如果是這樣,$ watchCollection或$監視book數組並在檢測到更改時保存它,或者使用angular-localforage並將數組直接綁定到localstorage。如果你想澄清這些技術,讓我們知道。如果這兩個問題都不存在,也許對問題的澄清會有所幫助。 – Beartums

+0

@Beartums抱歉誤會。我想要的只是編輯功能,它將:1.將數據保存在本地存儲中。 2.動態更改表格中的值。我在本地存儲中實現了保存數據,但在頁面重新加載之前,我看不到表中的更改。所以問題是如何讓它成爲可能。 – max

回答

1

@Max,我想我明白,但我承擔,如果這是無益的。首先,爲了清楚起見,我會在這裏使用對象。使用newBook對象添加了新圖書

<div class="addBookInputs"> 
     <input class="form-control" ng-model="newBook.bookName" placeholder="type name of the book"/> 
     <input class="form-control" ng-model="newBook.bookAuthor" placeholder="type author of the book"/> 
     <input class="form-control" ng-model="newBook.bookGenre" placeholder="type genre of the book"/> 
     <input class="form-control" ng-model="newBook.bookPrice" placeholder="type price of the book" type="number"/> 
     <span class=""> 
      <button class="btn btn-success" ng-click="addNewTask()">Add Book</button> 
     </span> 
    </div> 

然後,控制器,你只需要在初始設置(期間還獲得在本地存儲陣列的價值,我覺得你檢索從localStorage的語法錯誤)。在Add()函數中,我只需將新書添加到數組中,然後將數組保存到本地存儲中。

$scope.books = JSON.parse(localStorage.getItem('table')); 

$scope.newBook = {}; 

$scope.addNewTask = function() { 
    $scope.books.push(newBook); 
    $scope.newBook = {}; 
    localStorage.setItem("table", JSON.stringify($scope.books)); 
}; 

對於編輯對話框,我會傳遞書籍對象(書籍)和書籍(editBook)的angular.copy。然後,當編輯被批准時(在editBook中),您應該能夠修改angular.copy(editBook,book)而不會破壞引用。您的更改應該出現在書本中,然後您可以將它們保存到本地存儲。

這有幫助嗎?

更新:編輯功能。 (我建議你學習AngularUI。JQuery的被認爲是一種反模式的角度應用程序)

首先,在HTML中,你應該改變你的編輯按鈕的NG-點擊屬性是ng-click="enableEditor(book)"讓你通過這本書的參考到你的功能。這時可把功能是:

$scope.enableEditor = function(book){ 
    $scope.selectedBook = book; 
    $scope.dialogBook = angular.copy(book) 

    $('#editDisplay').dialog({ 
     modal: true, 
     resizable: false, 
     width: 400, 
     buttons: { 
      Accept: function() { 
       $(this).dialog("close"); 
       $timeout(function() { 
        angular.copy($scope.dialogBook,$scope.selectedBook); 
        localStorage.setItem("table", JSON.stringify($scope.books)); 
       }) 
      }, 
      Cancel: function() { 
       $(this).dialog("close"); 
      } 
     } 
    }); 
}; 

你需要$超時傳遞給控制器​​,就像$ HTML(這允許角拿起從對話框中的異步變化)。您還需要將對話框的html更改爲引用dialogBook.name,dialogBook.genre等。最後,價格輸入字段中的「數字」類型將不起作用,因爲您有小數點(我想只需將其更改爲文本並單獨進行驗證)。

你可以找到一個工作小提琴here

+0

哇!感謝您爲我的表添加新書的好例子。這真是很好的解決方案。非常簡單)但是在描述EDIT功能時可以更具體一些。謝謝 – max

+0

@max,酷。很高興它有幫助。我已經更新了編輯功能的答案 - 我不知道jqueryUI,因此您可能不得不查看概念而不是特定的代碼。 – Beartums

+0

在您的推薦過程中,我在上面的代碼片段中進行了修復。但不幸的是它不起作用。也許我做錯了什麼? – max