Este artigo foi traduzido por máquina.

Visão do cliente

Associações internas do Knockout para HTML e JavaScript

John Papa

Baixar o exemplo de código

John PapaNocaute traz uma rica implementação de vinculação de dados ao desenvolvimento HTML5 e JavaScript. Depois que você entender o conceito dos observáveis, a maneira mais fácil de deslizar em desenvolvimento com o nocaute é entender a variedade de ligações internas que oferece. Ligações internas da nocaute são a maneira mais simples de toque em seus recursos de ligação de dados e adicionar vinculação de dados robusto para muitos aspectos de seus apps HTML5. A coluna anterior introduziu Knockout, coberto seus vários tipos dos observáveis e explorou o controle das ligações internas do fluxo. Desta vez eu vou me aprofundar mais em ligações internas do Knockout. As amostras de código, que você pode baixar do archive.msdn.microsoft.com/mag201203ClientInsight, demonstre como usar as diversas ligações internas e explicar os cenários em que você pode querer usá-los.

Você pode baixar a versão mais recente do Knockout (atualmente 2.0.0) do bit.ly/scmtAi e referenciá-lo em seu projeto, ou você pode usar a extensão do Gerenciador de pacotes NuGet Visual Studio (disponível em bit.ly/dUeqlu) para fazer o download Knockout.

Quais são as ligações internas em nocaute?

Em seu nível mais básico, ligação de dados requer uma fonte de ligação (tais como um objeto JavaScript) e um destino para ligar para (um elemento HTML, por exemplo). A origem da vinculação é frequentemente chamada de um modelo de modo de exibição. O elemento de destino pode ter várias propriedades, por isso é importante saber qual propriedade de destino para ligar a, também. Por exemplo, se você quiser vincular sua propriedade de nome de modelo de exibição de texto de uma marca de entrada, você iria querer ligar para a associação de valor de nocaute. Neste caso, Knockout identifica a propriedade de destino através de uma das suas ligações internas: valor. As ligações internas de vazado permitem que você vincular a propriedades, bem como métodos de seu modelo de modo de exibição. Nocaute inclui muitas ligações internas que ligam exibir propriedades de modelo para elementos de target, como discutiremos neste artigo.

A sintaxe para usar as ligações internas deve incluir o nome da ligação Knockout e os pares de propriedade do modelo de exibição dentro da propriedade vincular dados de um elemento HTML. Se você quiser dados vincule a mais de uma propriedade no elemento HTML, basta separar as ligações por vírgulas usando esta sintaxe:

    data-bind="built-in-binding:viewmodel-property1, another-built-in-binding:viewmodel-property2"

Seguindo esse padrão, você pode vincular o valor do elemento de entrada para a propriedade de salePrice de modelo de modo de exibição, da seguinte forma:

    <input type="text" data-bind="value:salePrice " />

Ligações internas do nocaute permitem lidar com a maioria dos cenários de ligação, mas se você encontrar um cenário de ligação especializado que não é abordado, você pode criar ligações personalizadas com vazado, demasiado. Eu vou cobrir ligações personalizadas em um artigo futuro.

Ligações fundamentais: texto e html

Vamos mergulhar, explorando as ligações internas que Knockout oferece. Figura 1 mostra o modelo de modo que todos os exemplos neste artigo usará para suas ligações internas. Os dados de exemplo são para uma guitarra, mas é apenas para demonstrar as ligações.

Figura 1 modelo de modo de exibição com propriedades, aninhados filhos e métodos

my.showroomViewModel = {
  id: ko.observable("123"),
  salePrice: ko.observable(1995),
  profit: ko.observable(-7250),
  rating: ko.observable(4),
  isInStock: ko.observable(true),
  model: {
          code: ko.observable("314ce"),
          name: ko.observable("Taylor 314 ce")
  },
  colors: ko.observableArray([
          { key: "BR", name: "brown" },
          { key: "BU", name: "blue" },
          { key: "BK", name: "black"}]),
  selectedColor: ko.observable(""),
  selectedColorsForDropdown: ko.observableArray([]),
  selectedColorForRadio: ko.observableArray(),
  allowEditing: ko.observable(true),
  isReadonly: ko.observable(true),
    onSalesFloor: ko.observable(true),
    qty: ko.observable(7),
  photoUrl: ko.observable("/images/314ce.png"),
  url: ko.observable("http://johnpapa.
net"),
  details: ko.observable("<strong><em>This guitar rocks!</em></strong>"),
  checkboxHasFocus: ko.observable(false),
  textboxHasFocus: ko.observable(false),
  buttonHasFocus: ko.observable(false),
  userInput: ko.observable(""),
  setFocusToCheckbox: function () {
          this.checkboxHasFocus(true);
  },
  displayValue: function () {
          if (this.userInput().length > 0) {
                  window.alert("You entered: " + this.userInput());
          }
  },
  detailsAreVisible: ko.observable(false),
  showDetails: function () {
          this.detailsAreVisible(true);
  },
  hideDetails: function () {
          this.detailsAreVisible(false);
  },
  useUniqueName: ko.observable(true)
};
ko.applyBindings(my.showroomViewModel);

Talvez a ligação mais comum é a vinculação de texto. Quando o nocaute vê uma ligação de texto, ele define a propriedade innerText para o Internet Explorer, ou a propriedade equivalente em outros navegadores. Quando a associação de texto é usada, qualquer texto anterior será substituído. A vinculação de texto é freqüentemente usada para exibir valores em um intervalo ou uma div. Este exemplo vincula a propriedade de model.code do modelo de modo de exibição a uma extensão:

    <span data-bind="text: model.code"></span>

A vinculação de html não é usada tão frequentemente, mas é muito útil para processar conteúdo em HTML no seu modelo de modo de exibição. No exemplo a seguir, o conteúdo da propriedade html é processado, tornar o texto negrito itálico:

    <tr>
      <td><div class="caption">html</div></td>
      <td><div data-bind="html: details"></div></td>
      <td><span>details: </span><span data-bind="text: details"></span></td>
    </tr>

Você pode ver os resultados desses exemplos em Figura 2 (e todos os exemplos, executando a página 04-builtin-bindings.html no código de exemplo). Todos os exemplos mostram a ligação interna, o destino e os valores de origem do modelo de modo de exibição.

The Knockout Text and HTML Bindings
Figura 2 O texto do Knockout e ligações HTML

Vinculação de valores

Ligação de dados é indiscutivelmente mais útil para aplicativos que são muito interativos, por isso faz sentido que a maioria das ligações internas no bind do Knockout ajuda aos elementos de entrada e formulário, como listas de caixas de texto, caixas de seleção e suspenso. Vamos explorar estas ligações internas, primeiro demonstrando a versatilidade de vinculação de valor do Knockout.

O valor de ligação funciona com muitos do HTML input tipos para vincular uma propriedade de modelo de modo de exibição diretamente para o valor de um elemento HTML, como um botão de rádio ou caixa de seleção de caixa de texto. O exemplo a seguir mostra a propriedade de model.code de modelo de modo de exibição sendo ligada a uma caixa de texto. A propriedade é definida usando a função observável do Knockout, que torna a notificar o alvo quando altera o valor da fonte:

    <td><input type="text" data-bind="value: model.code"/></td>
    <td><span>model.code: </span><span data-bind="text: model.code"></span></td>

Se um usuário altera o valor na caixa de texto, o novo valor é enviado do destino (textbox) para a fonte (a propriedade de model.code do modelo do modo de exibição) quando o usuário tabula longe de textbox. No entanto, você também pode usar uma ligação especial do Knockout dizer nocaute para atualizar o destino para a origem em cada pressionamento de tecla. No próximo exemplo, o valor do textbox é ligado para a propriedade de salePrice do modelo de modo de exibição e a vinculação de valueUpdate está ligada a afterkeydown. valueUpdate é um parâmetro para a associação de valor que ajuda a definir quando a associação de valor deve ser atualizada. Aqui o código está dizendo a Knockout para atualizar de origem após cada tecla pressionada press (você pode experimentar este exemplo, executando o código de exemplo; os resultados são mostrados na Figura 3):

    <td><input type="text" data-bind="value: salePrice, valueUpdate: 'afterkeydown'"/></td>
    <td><span>salePrice: </span><span data-bind="text: salePrice"></span></td>

The Value Binding to Textboxes
Figura 3 O valor vinculativo para caixas de texto

Ligação de caixas de seleção e botões de rádio

Caixas de seleção podem ser dados ligados do Knockout verificado ligação. A associação verificada deve ser ligada a uma propriedade ou uma expressão que é avaliada como true ou false. Porque as propriedades do modelo de modo de exibição são definidas como observáveis, a caixa de verificação é actualizada quando altera a propriedade de origem. Da mesma forma, quando um usuário verifica ou desmarca a caixa de seleção, o valor é atualizado na propriedade do modelo de modo de exibição. O exemplo a seguir mostra a caixa de seleção está sendo associada a propriedade de isInStock (pelo modelo de modo de exibição do Figura 1; os resultados são mostrados na Figura 4):

    <td><input type="checkbox" data-bind="checked: isInStock"/></td>
    <td><span>isInStock: </span><span data-bind="text: isInStock"></span></td>

The Checked Binding
Figura 4 A ligação marcada

Você também pode usar a vinculação marcada para selecionar um botão de opção em um grupo de botões de opção. O exemplo a seguir mostra um conjunto de botões de opção cujos valores estão codificados todos os códigos de duas letras que representa uma cor; Quando um usuário seleciona uma cor através do botão de rádio, a propriedade checked é definida e a propriedade de selectedColorForRadio do modelo de modo de exibição é atualizada para o valor de duas letras:

    <td>
      <input type="radio" value="BR" data-bind=
        "checked:  selectedColorForRadio" /><span>brown</span>
      <input type="radio" value="BU" data-bind=
        "checked: selectedColorForRadio" /><span>blue</span>
      <input type="radio" value="BK" data-bind=
        "checked: selectedColorForRadio" /><span>black</span>
    </td>
    <td><span>selectedColorForRadio: </span><span data-bind=
      "text: selectedColorForRadio"></span></td>

Enquanto isso funciona perfeitamente bem, acho que é mais útil para vincular dados a lista de cores para uma série de botões de opção, que pode ser feito combinando as três ligações internas: valor, verificados e foreach. O modelo de modo de exibição em Figura 1 tem uma propriedade de cores, que é uma matriz de objetos que contêm o nome de cada cor e um valor de chave. A vinculação de foreach no próximo exemplo faz um loop através da propriedade de matriz de cores, configuração de valor da cada botão de opção vinculação à propriedade chave da cor e texto do intervalo de uma vinculação à propriedade de nome da cor:

    <td>
      <div data-bind="foreach: colors">
        <input type="radio" data-bind=
          "value:key, checked: $parent.selectedColorForRadio" />
           <span data-bind="text: name"></span>
      </div>
    </td>
    <td><span>selectedColorForRadio: </span>
      <span data-bind="text: selectedColorForRadio"></span></td>

Ligação verificada do botão de opção é definida como a propriedade de selectedColorForRadio do modelo de modo de exibição usando a função de pai $. No entanto, a ligação simplesmente não pode ser ligada diretamente a essa propriedade porque a vinculação de foreach mudou o contexto do modelo de modo de exibição para a propriedade de cores. Para ligar corretamente a propriedade do modelo de modo de exibição, o código precisa devolver pai do contexto (no caso o próprio modelo de modo de exibição). A função de pai do Knockout $ informa Knockout para referir-se a um nível acima na hierarquia de contexto, dados que vincula a vinculação verificada para a propriedade de selectedColorForRadio do modelo de modo de exibição. (Existem muitas funções úteis e dicas como esta que vou explorar no futuro artigos). Os resultados deste exemplo são mostrados em Figura 5.

The Checked and Value Bindings Used in Radio Buttons
Figura 5 O marcado e ligações de valor usadas em botões de opção

Listas suspensas de ligação

Listas suspensas têm várias propriedades importantes para carregar uma lista de itens, exibir um valor, use um valor de chave diferente e armazenar a seleção do usuário. Nocaute fornece uma ligação interna para cada um deles.

As opções de vinculação identifica uma lista de valores a serem exibidos, geralmente de uma propriedade de matriz sobre o modelo de modo de exibição. O exemplo nesta seção define as opções de vinculação para a propriedade de cores do modelo de modo de exibição. Às vezes, você deseja exibir um valor na lista suspensa, mas usar outro valor quando um usuário seleciona um item da lista. Ligações internas de optionsText e optionsValue do nocaute ajudam. A ligação de optionsText é definida como o nome de Cadeia de caracteres da propriedade para exibir na lista suspensa, entre as opções de vinculação. A ligação de optionsValue é definida como o nome de Cadeia de caracteres da propriedade para ligar para o valor selecionado do item na lista suspensa. Neste exemplo, a matriz de cores contém objetos com um nome e uma propriedade de chave, de que o nome será usado para o optionsText e a chave para o optionsValue. A associação de valor é definida como a propriedade de selectedColor de modelo de modo de exibição, onde a seleção do usuário será armazenada:

    <td>
      <div class="caption">options, value, optionsText, optionsValue</div>
      <div>select (single selection dropdowns)</div>
    </td>
    <td><select data-bind="options: colors, value: selectedColor,
       optionsText: 'name', optionsValue: 'key'" ></select></td>
    <td><span>selectedColor: </span><span data-bind="text: selectedColor"></span></td>

Se você deseja permitir várias seleções em uma lista suspensa, você primeiro adicionar a propriedade multiple para o elemento select do HTML. Você substituir ligação (singular) de selectedOption do Knockout com sua ligação (plural) selectedOptions:

    <td>
      <div class="caption">options, selectedOptions, optionsText, optionsValue</div>
      <div>select (multiple selection dropdowns)</div>
    </td>
    <td><select data-bind="options: colors,selectedOptions: selectedColorsForDropdown,
      optionsText: 'name', optionsValue: 'key'" multiple="multiple" ></select></td>
    <td><span>selectedColorsForDropDown: </span><span data-bind=
      "text: selectedColorsForDropdown"></span></td>

Porque o HTML selecione elemento está permitindo que várias seleções, a propriedade de selectedColorsForDropdown do modelo de modo de exibição (que é definida como a ligação interna selectedOptions) irá conter uma lista delimitada por vírgulas dos valores para as seleções.

Figura 6 mostra os resultados da seleção de ambas as cores azuis e pretas. Observe que as listas dropdown exibem o nome da cor (azul e preto), mas usam a chave (BU e BK) como os valores selecionados.


Figura 6 vinculando a listas suspensas

Ativando e desativando elementos Input

Nocaute fornece ligações internas para ativar e desativar elementos input. A vinculação de enable permitirá que o elemento de entrada se a propriedade a que está vinculado é avaliada como true e desativará o elemento se ele for avaliada como false. Disable binding faz exatamente o oposto:

    <td>
      <input type="checkbox" data-bind="checked: allowEditing"/>
      <input type="text" data-bind="enable: allowEditing, value:salePrice" />
    </td>
    <td><span>allowEditing: </span><span data-bind="text: allowEditing"></span></td>

Este exemplo de código demonstra que o valor de caixa de seleção é dados ligados à propriedade Exibir modelo allowEditing, que também está ligada à caixa de texto habilitar a ligação. Assim quando a caixa de seleção estiver marcada, a caixa de texto estiver habilitada; Quando está desmarcada, a caixa de texto está desactivada.

Em contraste, o exemplo seguinte demonstra como a caixa de seleção marcada a ligação é ligada para a propriedade de isReadonly do modelo de modo de exibição e o textbox desativar vinculação é definida como a propriedade isReadonly. Portanto, quando a caixa de seleção estiver marcada, a caixa de texto é desabilitada (os resultados de ambas as amostras podem ser vistos em Figura 7):

    <td>
      <input type="checkbox" data-bind="checked: isReadonly"/>
      <input type="text" data-bind="disable: isReadonly, value:salePrice" />
    </td>
    <td><span>is readonly: </span><span data-bind="text: isReadonly"></span></td>

Bindings for Enabling and Disabling Elements
Figura 7 ligações para ativar e desativar elementos

Vinculando o foco

Nocaute tem uma ligação interna denominada hasfocus que determina e define qual elemento tem o foco. A vinculação de hasfocus é útil quando você deseja que o foco a ser definido para um elemento específico em um formulário. Se vários elementos têm hasfocus vinculação com os valores que forem avaliados como verdadeiro, o foco será definido para o elemento que tinha sua hasfocus definido mais recentemente. Você pode definir a vinculação hasfocus para a palavra-chave true para mover o foco diretamente para um elemento. Ou você pode vinculá-lo a uma propriedade de modelo de modo de exibição, conforme mostrado no código de exemplo em Figura 8.

Figura 8 configuração a ligação Hasfocus

    <td>
      <input type="checkbox" data-bind="hasfocus: checkboxHasFocus"/>
      <input type="text" data-bind="hasfocus: textboxHasFocus"/>
      <button data-bind="click: setFocusToCheckbox, hasfocus:buttonHasFocus">
        set focus to checkbox</button>
      <br/>
      <span data-bind="visible: checkboxHasFocus">checkbox has focus</span>
      <span data-bind="visible: textboxHasFocus">textbox has focus</span>
      <span data-bind="visible: buttonHasFocus">button has focus</span>
    </td>
    <td>
      <span>checkboxHasFocus: </span><span data-bind="text: checkboxHasFocus">
        checkbox has focus</span>
      <br/>
      <span>textboxHasFocus: </span><span data-bind="text: textboxHasFocus">
        textbox has focus</span>
      <br/>
      <span>buttonHasFocus: </span><span data-bind="text: buttonHasFocus">
        button has focus</span>
    </td>

Este código define a ligação hasfocus adequadamente para uma caixa de seleção, caixa de texto e um elemento de botão para três propriedades de modelo de modo de exibição diferente. Quando o foco é definido para um desses elementos HTML, a correspondente ligação hasfocus define a propriedade de modelo exibição como true para esse elemento (e os outros como false). Você pode testar esse exemplo com o código para download, ou ver os resultados no Figura 9, onde um usuário tenha colocado o foco na caixa de texto.

Binding for Setting the Focus
Figura 9 ligação para definir o foco

Vinculação a visibilidade

Ligação visível da separação deve ser ligada a uma propriedade que é avaliada como true ou false. Esta ligação irá definir o estilo de exibição do elemento visível se true (verdadeiro ou um valor não-nulo) ou nenhum se false (false, 0, indefinido ou null).

O próximo exemplo mostra a vinculação da caixa de seleção marcada e a ligação visível textbox que ambos definidos para a propriedade de onSalesFloor do modelo de modo de exibição. Quando a caixa de seleção estiver marcada, a propriedade onSalesFloor é definida como true e a caixa de texto se torna visível. Quando a caixa de seleção estiver desmarcada, a propriedade onSalesFloor é definida como false e a caixa de texto não estiver mais visível (ver Figura 10):

    <td>
      <input type="checkbox" data-bind="checked: onSalesFloor"/>
      <input type="text" data-bind="visible: onSalesFloor, value:qty" />
    </td>
    <td>
      <span>onSalesFloor: </span><span data-bind="text: onSalesFloor"></span>
    </td>

Binding for Visibility
Figura 10 ligação para visibilidade

Ligações de evento

Nocaute suporta ligação a qualquer evento através de sua ligação interna do evento, mas também tem duas ligações internas especiais para clique e envie. A vinculação de clique deve ser usada em um elemento quando você desejar para ligar o evento click para um método em um modelo de modo de exibição. É mais frequentemente usado com um botão, de entrada ou um elemento, mas pode ser usado com qualquer elemento HTML.

O código a seguir define o clique no botão Vincular ao método de displayValue sobre o modelo de modo de exibição; em Figura 1, você pode ver que o método de displayValue sobre o modelo de modo de exibição simplesmente exibe a modo de exibição userInput propriedade do modelo (que está ligada à caixa de texto) com um alerta:

    <td>
      <input type="text" data-bind="value: userInput"/>
      <button data-bind="click: displayValue">display value</button>
    </td>
    <td>
      <span>userInput: </span><span data-bind="text: userInput"></span>
    </td>

Quando você deseja vincular um método de modelo de modo de exibição para um evento diferente de clique, você pode usar ligação de evento do Knockout. Porque a vinculação de clique é a ligação mais utilizados para eventos, é simplesmente um atalho para a ligação do evento.

Ligação do evento da separação permite que você ligar para qualquer evento. Para usar ligação de evento, você passar um objeto literal contendo nome valor pares para o nome do evento e o método de modelo de modo de exibição, separados por vírgulas. O exemplo de código a seguir define ligação de evento interno do Knockout de modo que os eventos mouseover e mouseout estão vinculados para os métodos showDetails e hideDetails no modelo de modo de exibição. Esses métodos definir o modo de exibição modelo observável Propriedade detailsAreVisible para true ou false, em conformidade:

    <td>
      <div data-bind="text:model.code, event: {mouseover: showDetails,
        mouseout: hideDetails}"></div>
      <div data-bind="visible: detailsAreVisible" style="background-color: yellow">
        <div data-bind="text:model.
    name"></div>
        <div data-bind="text:salePrice"></div>
      </div>
    </td>
    <td>
      <span>detailsAreVisible: </span><span data-bind="text: detailsAreVisible"></span>
    </td>

A segunda div define a ligação visível para os exibir detalhes do modelo­AreVisible propriedade, assim quando o usuário move o mouse sobre a primeira div, a segunda div torna-se visível. Quando o mouse é movido longe a primeira div, a segunda div já não é visível. Os resultados são mostrados na Figura 11. A vinculação de envio (não mostrado na Figure11) aceita qualquer entrada gesto que enviará um formulário HTML.

The Click and Event Bindings
Figura 11 O clique e ligações de evento

Ligações de estilo

Você pode vincular estilos com vazado usando o css e as ligações internas de estilo. A vinculação de css pode ser definida como um ou mais válidos css classe nomes. O exemplo a seguir mostra que o textbox tem seu valor de vinculação conjunto para a propriedade de lucro do modelo de modo de exibição e seu css associar conjunto para um literal de objeto. O literal de objeto contém um ou mais css classe nomes para aplicar e uma expressão correspondente que deve ser avaliada como verdadeiro ou falso:

    <td>
      <input data-bind="value:profit, css: {negative: profit() < 0,
        positive: !(profit() < 0), }"/>
    </td>
    <td>
      <span>profit < 0: </span><span data-bind="text: profit() < 0 ?
    'negative' : 'positive'"></span>
    </td>

Por exemplo, se a propriedade de lucro for avaliada como menor que 0, o css classe nomeado negativo será aplicado. Da mesma forma, a segunda expressão será avaliada e se é verdade, o css classe nomeado positivo será aplicado.

Enquanto eu recomendo usar classes css sempre que possível, às vezes você pode querer definir um estilo específico, bem como. Nocaute apoia esta com sua ligação interna de estilo. No exemplo a seguir, a caixa de texto muda de cor para vermelho se o lucro é menor que 0 e a verde se o lucro for maior que 0 (os resultados para o css e o estilo de ligações são mostrados em Figura 12):

    <td>
      <input data-bind="value:profit, style: {color: profit() < 0 ? '
    red' :
        'green'}"></input>
    </td>
    <td>
      <span>profit < 0: </span><span data-bind="text: profit() < 0 ? '
    red' :
        'green'"></span>
    </td>

Style Bindings
Figura 12 estilo Bindings

Ligação a outros atributos HTML

Enquanto nocaute tem muitas ligações internas, você certamente encontrará algumas situações para as quais nenhuma existe. Para estes, Knockout oferece a ligação interna attr, que permite que você a dados associar qualquer atributo a uma propriedade de modelo de modo de exibição. Isto é muito útil em muitos cenários comuns, tais como obrigatório o href e o título da um elemento:

    <td>
      <a data-bind="attr: {href: url, title: model.
    name}, text:model.code"></a>
    </td>
    <td><span>url: </span><span data-bind="text: url"></span></td>

Outro uso comum para a ligação de attr é fazer o elemento img vincular seu atributo src a propriedade view modelo photoUrl (você pode ver os resultados de ambos estes exemplos em Figura 13):

    <td>
      <img data-bind="attr: {src: photoUrl, alt: model.code}" class="photoThumbnail"/>
    </td>
    <td><span>photoUrl: </span><span data-bind="text: photoUrl"></span></td>

Binding to Element Attributes
Figura 13 vinculando a atributos de elemento

Resumindo

Este artigo explorou muitas das ligações internas que Knockout oferece. Existem alguns outros, mais notavelmente a ligação de modelo, que explicarei em um artigo futuro. Em qualquer caso, os conceitos são os mesmos. Determine a propriedade de vinculação que você deseja usar o elemento de destino e o membro de modelo de modo de exibição ao qual você deseja vinculá-lo. Uma vez que você segure observáveis do Knockout e sua variedade de ligações internas, você tem os blocos de construção fundamentais para criar robustos Web apps usando o padrão Model View ViewModel ou MVVM.

John Papa é ex-divulgador da Microsoft nas equipes do Silverlight e do Windows 8, onde apresentava o popular programa de TV do Silverlight. Ele tem apresentado mundialmente em palestras e sessões de conferências, como compilação, MIX, Professional Developers Conference, Tech·Ed, Visual Studio ao vivo! e DevConnections. Papa também é um colunista da Visual Studio Magazine (Papa’s Perspective) e autor de vídeos de treinamento com a Pluralsight. Siga-o no Twitter em twitter.com/john_papa.

Agradecemos ao seguinte especialista técnico pela revisão deste artigo: Steve Sanderson