使用AngularJS更新表中值的最佳实践

时间:2016-01-25 15:43:35

标签: javascript jquery angularjs jquery-ui

我正在尝试使用AngularJS创建3向绑定,以便可以动态地更改表中的值和localStorage。我也在使用jqueryUI对话窗口,我想要更新值,然后将其保存到表和localStorage。在ng-model指令的帮助下,我将值填充到对话框窗口。然后在accept按钮上,我将值保存到localStorage和表:

                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;
    };
});
&#13;
.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;
 }
&#13;
<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>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分: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));
};

对于编辑对话框,我会传递书籍对象(书籍)和书籍的angular.copy(editBook)。然后,当批准编辑时(在editBook中),您应该能够在不破坏引用的情况下使用angular.copy(editBook,book)。您的更改应显示在书籍中,然后您可以将它们保存到本地存储。

这有帮助吗?

更新:编辑功能。 (我建议你学习AngularUI。JQuery被认为是角度应用程序的反模式)

首先,在html中,您应该将编辑按钮的ng-click属性更改为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");
            }
        }
    });
};

您需要将$ timeout传递给控制器​​,就像$ html一样(这允许angular从对话框中获取异步更改)。您还需要更改对话框的html以引用dialogBook.name,dialogBook.genre等。最后,&#39;数字&#39;键入您的价格输入字段不会起作用,因为您有一个小数点(我只是将其更改为文本并单独进行验证)。

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