O Angular é bom na estrutura do MVVM, mas com uma estrutura tão grande e abrangente, não é baixa para aprender e levará pelo menos uma ou duas semanas para começar. O Knockoutjs se concentra na ligação dos dados e pode ser colocado em uso em apenas um ou dois dias; portanto, o custo de aprendizado não deve ser muito baixo! Em uma época em que a evolução do front-end é tão rápida, o custo de aprendizado também é um fator que deve ser considerado. Muitas vezes, nossos projetos não são tão complicados e não precisam de uma estrutura universal. Eles precisam de ferramentas simples e fáceis.
Antes de Knockoutjs
Suponha que estamos construindo um sistema de pedidos e precisamos exibir o preço unitário do produto e, em seguida, podemos calcular o preço total com base na quantidade de entrada e exibi -lo. Também é fácil de alcançar com o código nativo, o efeito é:
O código é o seguinte:
<!-Código html-> preço: <span id = "preço"> </span> <r /> conta: <input type = "text" id = "conta" value = "" placeholder = "digite a quantidade" /> <r /> sum: <span id = "sum"> < /span> // js codevar, pricenode = documentyrymentsy-g = "sum"> < /span> // js codevar, pricenode = documentyr = " document.getElementById ('conta'), sumnode = document.getElementById ('sum'), preço = 100, conta = 11, soma = preço * conta; // inicialize. pricenode.innerText = price; contanode.value = conta; sumnode.textContent = sum; // monitora a entrada do usuário da camada de exibição AccountNode.adDeventListener ('keydown', function; e) {window.setTimeout (function () {AccountNode.VoD.Value; Sum = Price;Bem, é bastante simples! Ah, a propósito, exibimos 50 itens por vez, e existem 10 tipos de displays, além de várias promoções, como comprar 5 caixas de Okamoto e obter um bastão de massa frita ...
Então, você conhece o problema da implementação nativa:
• Com o aumento da interrupção da interface do usuário e dos dados, a quantidade de código cresceu rapidamente e é difícil de manter
• Nomes baseados em consultas DOM, ID ou classe são difíceis de gerenciar
• Acoplamento de código alto, difícil de reutilizar
Introdução aos knockoutjs
Knockoutjs (a seguir referido como KO) parecia resolver os problemas acima. É uma biblioteca MVVM leve que se concentra na implementação da ligação de dados e visualizações. Ele não fornece aulas de interface do usuário e funções de roteamento, e é muito rápido começar. Ao mesmo tempo, desde que o KO está fora há alguns anos, tornou -se uma estrutura relativamente madura. Ao fazer algumas páginas que exibem mais dinamicamente, Ko é sem dúvida uma escolha melhor. Não vou dizer muito sobre MVVM, apenas uma imagem para confundir:
O KO é baseado em três recursos principais (Introdução ao site oficial):
1. Rastreamento de observáveis e dependência: use observáveis para configurar uma cadeia de relacionamento implícita entre os dados do modelo para transformação e ligação de dados.
2. Liglas declarativas: use a sintaxe simples e fácil de ler para vincular facilmente dados do modelo aos elementos DOM.
3.
Usar KO é muito simples. Basta baixá -lo diretamente no site oficial (http://knockoutjs.com/index.html) e introduzi -lo com <cript>.
Objetos observáveis
Reescreva o exemplo acima usando o KO (preço personalizado, que foi um dos meus desejos de infância):
O código se parece com o seguinte:
<!-html code-> <div id = "One"> Preço: <inspira tipo = "text" data-bind = "valor: preço" espaço reservado = "por favor, digite o preço unitário" /> <r /> conta: <input type = "text" data-bind = "value:" conta "someholder =" digite summ " /<r /> sum: <span-bind = data-bind:" ViewModel = function (p, a) {// Defina como um objeto observável e inicialize this.price = ko.observable (p); this.Account = ko.observable (a); // Ao chamar o ko, isso será passado. this.sum = ko.pureComputed (function () {// Como o objeto observável é um objeto de função, você precisa usar o preço () para ler o valor atual. 10); // Aplique essa ligação e a ligação começa a entrar em vigor Ko.ApplyBindings (VM);1) Vejamos o código HTML primeiro:
Você pode ver que um par de valores-chave como o data-bind = "xx: oo" é adicionado a cada tag. Esta é a sintaxe de ligação de KO. O que o XXOO representa? (XXOO? O autor ainda é criança ...) A partir do exemplo, podemos ver que os atributos de XX são tags, que podem ser atributos de tag, como texto, valor, classe, verificado etc. e, de fato, eles também podem ser cliques, foco, carga e outros eventos DOM. OO parece uma variável, mas não é uma variável, mas um objeto de função. A execução dessa função (com um ()) pode obter o valor limitado correspondente. Através do XXOO, os atributos ou eventos de um elemento podem ser vinculados aos objetos de função em JS (se XXOO, você deve ser responsável um pelo outro), essa é a ligação declarativa de Ko. A definição de ligação é na verdade um modo de observador, mas essa é uma ligação de mão dupla. O editor e o assinante assinam as mensagens um do outro. Esta é a ligação bidirecional do MVVM. O resultado da ligação bidirecional de KO é que uma parte pode atualizar automaticamente a outra parte mudando, ou seja, os dados e a camada de apresentação estão fortemente unidos através do ViewModel. O efeito de ligação é semelhante a:
2) Vamos dar uma olhada no código JS:
Você pode ver que um objeto ViewModel é definido em JS e o OO limitado no HTML é operado no objeto. Existem duas operações principais aqui: ko.observable () e ko.pureComputed ().
• Ko.observable (p): veja o nome, este é o método de definir objetos observáveis. O parâmetro passado P é o valor inicializado. Os parâmetros aqui podem ser o tipo de dados básico ou um objeto JSON. Depois de ser definido como observável, isso significa que o sistema observará esse valor o tempo todo. Se o P no ViewModel ou o P nas alterações do objeto ligado causará um evento de atualização e todos os lugares que usam esse valor serão atualizados para o estado mais recente. Obviamente, objetos observáveis são relativamente consumidos por desempenho; portanto, para valores que não requerem alterações dinâmicas (como preços), não definem como objetos observáveis. Obviamente, ele ainda precisa ser colocado em ViewModel para a inicialização centralizada.
• Nota: o objeto observável retornado por ko.observable (p) é um objeto de função; portanto, você precisa usar o price () para ler o objeto observável; Da mesma forma, definir o objeto observável requer preço (newvalue) para usar o preço (newValue). O que é mais atencioso é que, ao definir, ele suporta a escrita em cadeia: ViewModel.Price (100) .ACANTE (10).
• ko.pureComputed () é o chamado rastreamento de dependência. Aqui está o preço unitário * A quantidade é igual ao preço total. Observe que você não pode usar diretamente isso.sum = this.price () * this.account (); para especificar a soma. Este método de escrita não pode atualizar dinamicamente o objeto ligado, mas altera dinamicamente a variável SUM, mas outras operações são necessárias para atualizar o objeto ligado. Portanto, os valores de ligação relacionados aos cálculos devem ser definidos usando a função de cálculo de KO. Obviamente, o objeto de função retornado também é um objeto de função. Além disso, o KO também possui uma função calculada, que também pode ser definida, mas é recomendável usar o Pure para melhorar o desempenho.
• Preste atenção ao método de escrita aqui: ko.pureComputed (fn, isto), isto é, vincular FN ao escopo do ViewModel, que é na verdade a chamada/aplicação no JS. Como este é um objeto KO ao executar funções internas do KO, para obter o escopo do objeto ViewModel, isso precisa ser transmitido para o método de escrita acima. Obviamente, você também pode usá -lo para salvar o objeto ViewModel fora da função KO e, em seguida, usá -lo dentro da função KO para chamar o objeto ViewModel. Assim:
var que = this; this.sum = ko.pureComputed (function () {return that.price () * that.account ();});Depois de definir o construtor de viewmodel, um objeto ViewModel é instanciado e, em seguida, o método ko.applybindings () é usado para fazer a ligação entrar em vigor. Não perca esta etapa.
Modo de página simples usando KO:
<!-Código html-> <span data-bind = "text: bindText"> </span> // js codevar viewModel = {bindText: ko.observable ('initValue')}; ko.applybindings (ViewModel);Para resumir, é: use data-bind = "xx: oo" para declarar vinculação em html, crie um viewmodel em js e defina um objeto observável e, finalmente, aplique a ligação.
Array de objeto observável
Vamos dar uma olhada no uso de matrizes de objetos observáveis. Em Ko, matrizes e variáveis não podem ser misturadas como JS. Para objetos de matriz, você precisa usar o ko.observablearray ([…,…]) da mesma maneira. Da mesma forma, os elementos da matriz podem ser de tipos básicos ou objetos JSON. A matriz de objeto observável em KO possui uma série de métodos de operação de matriz, como Slice (), Sort (), push (), etc. O efeito é o mesmo que os métodos de operação de matriz JS nativa. A única diferença entre as alterações feitas através do método KO será notificada ao assinante para atualizar a interface, mas o método JS não atualizará a interface. Aqui está um exemplo simples:
<!-HTML Code-> <select data-bind = "Opções: list"> </select> // js codevar vm = {// list: ko.observableArray () list: ko.observableArray (['Luffy', 'zoro', 'Sanji'])};Ponto -chave: KO monitora o estado da matriz, não o estado do próprio elemento. Ou seja, quando o estado da matriz mudar (adicionando elementos), o evento KO será acionado para causar a atualização do objeto ligado, mas as alterações nos elementos dentro da matriz (como alterações de valor) não serão monitoradas e não podem acionar o evento KO. Por exemplo:
O uso de métodos nativos para alterar dinamicamente Luffy para Lucy no console não atualizará a página da interface do usuário, enquanto o uso da matriz de Ko para alterar a matriz atualizará imediatamente a página. Vale a pena notar que, quando refrescante, as mudanças anteriores também serão atualizadas (Luffy> Lucy). Em outras palavras, as variáveis na memória JS realmente mudaram, mas ainda há uma falta de ação para atualizar o DOM. Como você pode ver aqui, o método de ler uma matriz é vm.List () [0], porque a lista também é um objeto de função e a execução do valor de retorno é o conteúdo da lista que queremos. Da mesma forma, você pode redefinir a matriz de objetos observáveis através da VM.List (["Girl", "Girl"]) e atualizar a interface do usuário imediatamente.
Se você precisar reagir dinamicamente as alterações dos elementos da matriz na interface do usuário, precisará definir os elementos da matriz para objetos observáveis e, em seguida, usar o método de Ko para alterar o valor do elemento da matriz. Observe que é usar a lista de métodos de Ko () [0] ("Lucy")!
Existem dois tipos de métodos para operar matrizes de objetos observáveis. Um é o mesmo nome que o método nativo JS Array: POP, Push, Shift, Netfift, Reverse, Classin, Splice. Esta parte é a mesma que o uso e os efeitos do método JS nativo, então não o repetirei novamente.
Alguns outros métodos não estão disponíveis no JS, principalmente o seguinte:
• Remova (algum ITEM) - Exclua todos os itens de elemento com valores iguais a algum ITEM e retorne -os em um formulário de matriz. O que isso significa aqui é que você não pode excluir diretamente a primeira lista de itens.Remove (0), mas use a lista de formulários.Remove (list () [0]) para excluí -lo. Em resumo, o parâmetro passado deve ser o valor do item do elemento. Ele pode ser usado na forma de lista () [0], ou você pode inserir diretamente a sequência de valores (como "Luffy").
• Remover (função (item) {retornar item.age <18;}) - exclua todos os itens de elemento com atributos de idade menores de 18 e devolva -os como uma matriz. Esse uso não é diferente das funções de ordem superior da matriz comum. O item é passado como um parâmetro de uma função de ordem superior. Ao iterar através da matriz, o item é excluído quando o valor de retorno da função de ordem superior for o valor verdadeiro, caso contrário, ele será destinado ao próximo item.
• Removeall (['Chad', 132, indefinido]) - Remova todos os itens de elemento com valores iguais a 'chad' ou 123 ou indefinidos e devolva -os como uma matriz.
• removeall () - remove todos os itens e retorna como uma matriz.
Dicas: Ao lidar com objetos observáveis, se houver muitos objetos e interações frequentes, a atualização imediatamente a cada alteração consumirá desempenho. Neste momento, você pode usar a extensão myobservablearray.extend ({ratelimit: 1000}) para definir uma atualização atrasada. Por exemplo, ao inserir continuamente elementos na matriz observável, você pode definir um tempo de ciclo de 1000ms para concentrar todas as operações dentro de 1000ms em uma atualização para evitar a deterioração do desempenho causada por operações frequentes de DOM.
Resumir
Este artigo apresenta principalmente o conceito mais importante em KnockoutJs: Objetos Observáveis (matrizes). Um objeto observável é essencialmente um objeto de função. Ao operar objetos observáveis através do método KO, a interface do usuário pode ser atualizada dinamicamente. Este é o método recomendado. Ao mesmo tempo, você também pode operar objetos observáveis através do método JS nativo, mas o método nativo não atualizará a tela da interface do usuário e precisará esperar até que o próximo evento de atualização seja atualizado na interface do usuário.