Em knockout js, vejo os modelos de declaração declarados como:
var viewModel = {
firstname: ko.observable("Bob")
};
ko.applyBindings(viewModel );
ou:
var viewModel = function() {
this.firstname= ko.observable("Bob");
};
ko.applyBindings(new viewModel ());
Qual é a diferença entre os dois, se houver?
Eu encontrei essa discussão no grupo do Google do knockoutjs, mas isso realmente não me deu uma resposta satisfatória.
Eu posso ver um motivo para querer inicializar o modelo com alguns dados, por exemplo:
var viewModel = function(person) {
this.firstname= ko.observable(person.firstname);
};
var person = ... ;
ko.applyBindings(new viewModel(person));
Mas se eu não estou fazendo isso, importa qual estilo eu escolho?
prototype
(métodos que, por exemplo, costumam buscar dados do servidor e atualizar o modelo de exibição de acordo). No entanto, você ainda pode obviamente declará-los como propriedade de um objeto literal, portanto não vejo realmente diferença.Respostas:
Existem algumas vantagens em usar uma função para definir seu modelo de exibição.
A principal vantagem é que você tem acesso imediato a um valor
this
igual à instância que está sendo criada. Isso significa que você pode fazer:Portanto, seu observável calculado pode ser vinculado ao valor apropriado de
this
, mesmo se chamado de um escopo diferente.Com um objeto literal, você teria que fazer:
Nesse caso, você pode usar
viewModel
diretamente no observável calculado, mas ele é avaliado imediatamente (por padrão) para que você não possa defini-lo no literal do objeto, comoviewModel
não é definido até que o literal do objeto seja fechado. Muitas pessoas não gostam que a criação do seu modelo de visualização não seja encapsulada em uma chamada.Outro padrão que você pode usar para garantir que
this
seja sempre apropriado é definir uma variável na função igual ao valor apropriado dethis
e usá-la. Seria assim:Agora, se você estiver no escopo de um item e chamada individual
$root.removeItem
, o valor dethis
será realmente os dados vinculados nesse nível (que seria o item). Usando self neste caso, você pode garantir que ele esteja sendo removido do modelo de vista geral.Outra opção está usando
bind
, que é suportada por navegadores modernos e adicionada pelo KO, se não for suportada. Nesse caso, seria semelhante a:Há muito mais a ser dito sobre esse tópico e muitos padrões que você pode explorar (como padrão de módulo e padrão de módulo revelador), mas basicamente o uso de uma função oferece mais flexibilidade e controle sobre como o objeto é criado e a capacidade de referenciar variáveis que são privadas para a instância.
fonte
self
ethis
são os mesmos, portanto, ambos serão equivalentes. Na função removeItem,self
torna-se mais útil, poisthis
não seria mais a instância atual quando executada no contexto de um item filho.Eu uso um método diferente, embora semelhante:
Duas razões:
this
, o que pode confundir quando usado emko.computed
s etcnew viewModel()
)fonte
My viewModel is a singleton, I don't need to create multiple instances (i.e. new viewModel())
mas não está claro o que você está tentando dizer:I don't need to create multiple instances
pode ser que você venha com mais uso para que se possa entender a vantagem de sua abordagem. obrigadofunction
é porque você o executaria mais de uma vez. No entanto, no meu exemplo sobre, é uma função anônima chamada imediatamente, portanto, não será criada mais de uma vez. É muito semelhante ao Literal de Objetos no exemplo acima, mas oferece mais isolamento