As listas de atributos devem ser familiares para todos. Normalmente, a lista de atributos feita em HTML5 é provavelmente um menu suspenso. E em muitos casos, a lista suspensa não é bonita o suficiente. Tentei usar o HT for Web para realizar a função de clicar em um botão na barra de propriedades para abrir uma caixa de seleção multifuncional e selecionar os dados recebidos. Acho que a prática geral é relativamente simples e conveniente, então vou compartilhar. isso com você aqui.
renderizaçõeshttp://www.hightopo.com/demo/propertyEditor/index.html
Implementação de código Mapa de topologiaNa renderização acima, podemos ver que a página inteira está dividida em 3 partes, a parte da topologia graphView à esquerda, a parte da tabela tableView no canto inferior direito e a parte do atributo propertyView no canto superior direito. Primeiro dividimos a cena inteira e depois adicionamos conteúdo específico a cada parte:
gv = new ht.graph.GraphView();var tablePane = new ht.widget.TablePane(gv.dm());//Componente do painel de tabela propertyView = new ht.widget.PropertyView(gv.dm());/ /formPane está em propertyView, então você deve primeiro definir var rightView = new ht.widget.SplitView(propertyView, tablePane, 'v', 0,4);//Divide o componente, v é dividido em camadas superior e inferior, a proporção é 0,4:0,6rightView.getView().style.borderLeft = '1px solid #000';var borderPane = new ht .widget.BorderPane( );//Componente do painel de borda borderPane.setRightView(rightView, 400);//Definir borderPane O componente direito é rightView com largura de 400borderPane.setCenterView(gv);//Defina o componente intermediário borderPane como gv borderPane.addToDOM();//Adicione o componente borderPane ao corpo
As novas partes no código acima são todos componentes encapsulados em HT, que são equivalentes a classes. Aqui está uma explicação do componente dividido SplitView. O componente dividido é usado para dividir dois subcomponentes para a esquerda e para a direita ou para cima e para baixo. -components podem ser componentes fornecidos pela estrutura HT ou podem. É um componente nativo do HTML. O subcomponente é posicionado de forma absoluta com a posição absoluta. Os parâmetros neste componente são (componente esquerdo ou componente superior, componente direito ou. componente inferior, h significa divisão esquerda e direita v Indica a divisão superior e inferior. O valor padrão da posição de divisão é 0,5. Se o valor da configuração for 0~1, será dividido por porcentagem. Maior que 1 representa a largura ou altura absoluta do componente esquerdo ou do componente superior. Menos de 1 representa a largura ou altura absoluta do componente direito ou inferior); e o componente do painel BorderPane é um contêiner de layout, que pode colocar subcomponentes em cinco áreas: superior, inferior, esquerda, direita e centro. Os subcomponentes podem ser componentes fornecidos pela estrutura HT ou podem ser componentes nativos do HTML. O componente está posicionado. Execute o posicionamento absoluto para o modo absoluto. Aqui combino SplitView e BorderPane para dividir a cena em três partes. Por fim, lembre-se de adicionar o contêiner de layout final ao corpo ou qualquer tag HTML para que possa ser exibido na interface. A definição de addToDOM é a seguinte:
addToDOM = function(){ var self = this, view = self.getView(), //Obter o div subjacente deste componente style = view.style; //Obter o atributo de estilo do div subjacente document.body.appendChild( view) ; //Adicione o div subjacente ao corpo style.left = '0'; //HT por padrão define os componentes para determinar o posicionamento absoluto, então a posição precisa ser definida style.right = '0'; topo = '0'; style.bottom = '0'; window.addEventListener('redimensionar', function () { self.iv(); }, false });
Os componentes HT são geralmente incorporados em contêineres como BorderPane, SplitView e TabView. O componente HT mais externo requer que o usuário adicione manualmente o elemento div subjacente retornado por getView() ao elemento DOM da página. , Quando o tamanho do contêiner pai muda, se o contêiner pai for um componente de contêiner predefinido do HT, como BorderPane e SplitView, o contêiner HT chamará automaticamente a função invalidate do componente filho recursivamente para notificar a atualização. Mas se o contêiner pai for um elemento html nativo, o componente HT não pode saber que precisa ser atualizado. Portanto, o componente HT mais externo geralmente precisa ouvir o evento de alteração do tamanho da janela e chamar a função de invalidação do mais externo. componente a ser atualizado.
A cena está criada. Para mostrar as diferenças nos atributos correspondentes a diferentes nós, adicionamos sete nós ao mapa de topologia:
function initModel(){ var name = device; var count = 0; var root = createNode(name + count++, name + (++count));//Parâmetro 1 é nome, parâmetro 2 é tag root.setImage('. /símbolos/sala de computadores/servidor.json'); root.setName('servidor'); root.s('label.position', 3); gv.sm().ss(root);//O nó raiz é selecionado por padrão para (var i = 0; i < 2; i++) { var iNode = createNode(name + count++, name + (++count) );/ /O parâmetro 1 é o nome, o parâmetro 2 é a tag createEdge(root, iNode); for (var j = 0; j < 2; j++) { var jNode = createNode(name + count++, name + (++contagem)); createEdge(iNode, jNode);
A declaração da função createNode é a seguinte:
function createNode(nome, tag){//Criar nó node flag++; var node = new node.setName(name); node.setTag(tag); /XX subsistema.json'); node.a('oculto', false);//Atributos personalizados, você pode controlar node.a('hidden') para controlar a visibilidade dos nós node.a('Interface type', 'SATA'); ') ; if(flag % 2 === 0){ node.a('tipo de interface', 'IDE'); node.a('placa gráfica', 'ATI'); posição', 11); gv.dm().add(node);//Adiciona nós ao contêiner de dados DataModel node.tablePane1 = createTableView(serviceType, dataModel1);//Cria um painel de tabela node.tablePane2 = createTableView(serviceSize, dataModel2); tablePane3 = createTableView(versão, dataModel3); createFormPane(node.tablePane1);//Cria um painel de formulário node.formPane1.title = 'Type';//Para preparar o título da caixa de diálogo subsequente node.formPane2 = createFormPane(node.tablePane2); title = 'Memória'; node.formPane3 = createFormPane(node.tablePane3); if(flag % 3 === 0){ node.formPane3.v('tag', 'Lenovo Server X3650M5 8871'); } node.a('model', node.formPane3.v('tag'));
Controlamos a visibilidade do nó controlando o atributo oculto deste nó e usando a função de filtro visual setVisibleFunc em graphView:
gv.setVisibleFunc(function(data){ if(data.a('hidden')){ return false; } return true;});Painel Propriedades
Com nós, é natural exibir atributos. Junto com os valores no painel da tabela tablePane abaixo, são adicionados um total de sete atributos:
function createProperty(){//Criar propriedades propertyView.addProperties([ { name: 'name',//Obter o atributo name, combinado com o atributo accessType para finalmente obter acesso aos atributos do nó. O valor padrão de accessType é nulo, tal como nome é idade, use o método get/set ou is/set de getAge() e setAge(98) para acessar (nome aqui é nome, então obtenha-o por meio de getName()) displayName: 'Nome' // Defina o valor do texto de exibição do nome do atributo}, { name: 'hidden', // Obtenha o atributo oculto displayName: 'Ocultar este nó', accessType: 'attr', // Se o nome estiver oculto, use getAttr( 'hidden') e setAttr('hidden', false) para acessar o ícone: 'images/alert.gif', //Defina o ícone valueType exibido no lado esquerdo do nome do atributo: 'boolean', //Usado para solicitar ao componente que forneça um renderizador adequado Tipo booleano, exibido como uma caixa de seleção editable: true //Definir se a propriedade é editável}, { name: 'grade', displayName: 'Type' , accessType : 'attr', drawPropertyValue: function(g, property, value, rowIndex, x, y, w, h, data, view){//Renderização de valor de atributo personalizado function var cb = function(v) { data.a('nota', v } return fillFormPane(data.formPane1, w, h, data.tablePane1, serviceType, cb); { nome: 'número', displayName: 'memória', accessType: 'attr', drawPropertyValue: function(g, property, value, rowIndex, x, y, w, h, data, view){ var cb = function(v) { data.a('número', v } return fillFormPane(data.formPane2, w, h, data.tablePane2, serviceSize, cb); { nome: 'Tipo de interface', accessType: 'attr', displayName); : 'Tipo de interface' }, { nome: 'Placa gráfica', accessType: 'attr', displayName: 'Placa gráfica' }, { nome: 'Modelo', accessType: 'attr', displayName: 'Modelo', } ]);}
O valor de retorno do atributo drawPropertyValue no terceiro e quarto atributos é a função fillFormPane Os parâmetros desta função são (componente de formulário formP, largura do componente de formulário w, altura do componente de formulário h, clique no botão no componente de formulário para gerar a tabela. componente tableP na caixa pop-up, o conteúdo da matriz arr no componente da tabela, a função cb atribui o valor retornado clicando duas vezes na linha no componente da tabela à caixa de texto ht.widget.TextField no formulário).
O primeiro parâmetro formP é a criação do componente de formulário. A criação do componente de formulário consiste em criar um componente de formulário e adicionar uma caixa de texto e um botão ao componente de formulário. Esta etapa também é bastante simples em HT:
function createFormPane(tPane) {//Cria um painel de formulário var formPane = new ht.widget.FormPane(); //Define o espaçamento ao redor do formulário e o conteúdo do componente var tField = new ht.widget.TextField();//Cria uma caixa de texto tField.setText('');//O conteúdo da caixa de texto está vazio tField.setDisabled(true);//A caixa de texto está inoperável formPane.addRow( [// Adicione uma linha ao formulário { id: 'tag', //O atributo de identificação exclusivo pode ser obtido através de formPane.getItemById(id) e adicionado ao elemento do objeto item correspondente: O valor tField//Attribute pode ser elementos nativos HTML, informações de texto auto-desenhadas dentro do FormPane e componentes integrados do HT, como Button, CheckBox e ComboBox, etc.}, { button:{//Depois de definir este atributo, HT irá ser construído automaticamente com base no valor do atributo objeto ht.widget.Button e salvo no rótulo do atributo do elemento:'...',//O conteúdo do texto no botão onClicked: function(){//Evento de clique do botão for(var eu = 0; tPane.dm().size(); i++){//Set tablePane para selecionar o valor correspondente ao formPane por padrão var data = tPane.dm().getDatas().get(i); 'valor' ) === formPane.v('tag')){ tPane.sm().ss(dados); formPane);//O que é retornado é criar uma caixa de diálogo, cujo conteúdo é o painel da tabela} } }], [0.5, 0.1]);//Define a proporção de exibição do primeiro elemento e do segundo elemento em o componente da tabela. Este componente de tabela possui apenas dois elementos no total, uma caixa de texto e um botão, com proporções de 0,5 e 0,1 respectivamente return formPane;}
O processo de criação da função createDialog também é simples e claro. O título, tamanho, conteúdo, etc. da caixa de diálogo são configurados através do método setConfig(config). Passei um parâmetro da tabela tPane para createDialog, que é usado como. o conteúdo exibido na caixa de diálogo:
function createDialog(tPane){//Cria uma caixa pop-up dialog.setConfig({ title: gv.sm().ld().getName()++formPane.title,//O título do conteúdo da caixa de diálogo: tPane, // Define diretamente o conteúdo da caixa pop-up para a largura do painel da tabela: 400, //Especifica a largura da caixa de diálogo altura: 200, arrastável: true, // Especifique se a caixa de diálogo pode ser arrastada e fechada: true, // Indica se o botão fechar deve ser exibido: true, // Indica se a caixa de diálogo pode ser maximizada: wh, // Mova o mouse para a direita da caixa de diálogo O tamanho da caixa de diálogo pode ser alterado no canto inferior, o que significa que a largura e a altura podem ser ajustadas: [//Adicionar dois botões { label: 'Cancelar', ação: function(){ dialog.hide() } }, { label: 'OK ', } ] }); dialog.show();//Mostra caixa de diálogo}
O quarto parâmetro do componente tableP não é nada especial. Ele apenas cria um componente de formulário e depois adiciona colunas ao componente de formulário. As etapas são simples e o código também é bastante simples:
function createTableView(arr, dm){//Criar componente de tabela var tableView = new ht.widget.TableView(dm); tableView.addColumns([//Adicionar informações de coluna em lotes usando parâmetros de array json{ displayName: 'ID', / /Obter o conteúdo do nome da coluna do cabeçalho da tabela drawCell: function(g, data, selected, column, x, y, w, h, tableView){//Método de renderização de célula personalizado var id = tableView.getRowIndex(data);//Retorna o índice da linha onde o objeto de dados está localizado ht.Default.drawText(g, 'row' + (id + 1), null, null, x, y, w, h, 'center');//Parâmetros de texto do desenho (g objeto pincel, valor conteúdo do texto, fonte do texto, cor do texto, coordenada x quando o desenho começa, coordenada y quando o desenho começa em y, largura ao desenhar w, altura ao desenhar h , alinhar o alinhamento horizontal do texto, vAlign alinhamento vertical do texto) } }, { displayName: 'Nome', drawCell: function(g, data, selected, column, x, y, w, h, tableView){ var id = tableView.getRowIndex(dados); var info = arr[id]; }
Depois de explicar os parâmetros em fillFormPane, vamos dar uma olhada em como esta função é definida. Basicamente, a última etapa é clicar no elemento no componente de tabela tablePane e retornar este elemento para a caixa de texto textField no componente de formulário formPane:
função fillFormPane(formP, w, h, tableP, arr, cb){//formpane à direita if(formP === indefinido){ return } formP.setWidth(w); setHGap (0); if(formP.v('tag') === 'indefinido' || formP.v('tag') === '') { formP.v('tag', arr[0]); } tableP.onDataDoubleClicked = function(data){//Callback quando a linha de dados no componente da tabela é clicada duas vezes var v = arr[data.a('index ') ]; formP.v('tag', v);//Define o valor do elemento do item correspondente de acordo com o id, que é a abreviatura de setValue O elemento com o id da tag é a caixa de texto dialog.hide(. ); se (cb){cb(v);} //Se o parâmetro cb for passado, defina o valor de data.a('number')/data.a('helloName') para o valor da linha clicada duas vezes na tabela, ou seja, atribuído ao terceiro e quarto atributos} tableP.onDataClicked = function(data){//Callback dialog.getConfig().buttons[1].action = quando a linha de dados no componente da tabela é clicada function(){//Clique em OK para prosseguir com as seguintes operações var v = arr[data.a('index')]; formP.v('tag', v); {cb(v);} } }; return formP.getView();}
função fillFormPane(formP, w, h, tableP, arr, cb){//formpane à direita if(formP === indefinido){ return } formP.setWidth(w); setHGap (0); if(formP.v('tag') === 'indefinido' || formP.v('tag') === '') { formP.v('tag', arr[0]); } tableP.onDataDoubleClicked = function(data){//Callback quando a linha de dados no componente da tabela é clicada duas vezes var v = arr[data.a('index ') ]; formP.v('tag', v);//Define o valor do elemento do item correspondente de acordo com o id, que é a abreviatura de setValue O elemento com o id da tag é a caixa de texto dialog.hide(. ); se (cb){cb(v);} //Se o parâmetro cb for passado, defina o valor de data.a('number')/data.a('helloName') para o valor da linha clicada duas vezes na tabela, ou seja, atribuído ao terceiro e quarto atributos} tableP.onDataClicked = function(data){//Callback dialog.getConfig().buttons[1].action = quando a linha de dados no componente da tabela é clicada function(){//Clique em OK para prosseguir com as seguintes operações var v = arr[data.a('index')]; formP.v('tag', v); {cb(v);} } }; return formP.getView();}
A exibição da barra de propriedades no canto superior direito termina aqui. O painel da tabela no canto inferior direito é criado da mesma maneira. Você pode ler o código para entendê-lo sozinho.
layout automáticoFinalmente, vamos falar sobre a organização dos nós em toda a interface. O componente de layout automático autolayout em HT fornece vários tipos de algoritmos para organizar automaticamente as posições dos nós com base no relacionamento entre nós e conexões. O layout automático é frequentemente usado em cenas onde há muitos elementos gráficos ou relações de conexão complexas, dificultando arrastá-los e posicioná-los manualmente. Apresento cada método de layout através de botões. Clique no botão correspondente e o método de layout será automaticamente apresentado de acordo com o método de layout definido pelo botão pressionado:
Primeiro, crie uma nova instância, passe o objeto que precisa de layout automático, que pode ser DataModel, graphView e graph3dView, e então defina o método de layout padrão:
autoLayout = new ht.layout.AutoLayout(gv);setTimeout(function(){ layout('towardsouth', true);//Porque antes de a imagem ser carregada, o layout automático é organizado de acordo com o tamanho padrão do nó} , 200);
Em seguida, crie um painel de formulário formPane, adicione-o ao corpo e coloque-o no canto superior esquerdo do corpo. Não vou colar todo o código, apenas exibir o botão do primeiro layout:
function createDirectionForm(){ var form = new ht.widget.FormPane(); form.setWidth(200);//Definir a largura do formulário form.setHeight(80); formulário .getView().style.background = '#fff'; formulário.getView().style.boxShadow = '4px 16px 16px rgba(0, 0, 0, 0.1)';//Definir o estilo de sombra form.addRow([//Esta linha é retirada separadamente como o título { element: 'Auto Layout:',//Texto exibido}] , [0.1]);//Há apenas um objeto no array, basta definir a largura de um objeto form.addRow([ { button: { icon: 'Layout/South Layout.json', onClicked: function(){ layout('towardsouth', true }, background: null, labelColor: '#fff', groupId: 'btn', toolTip: 'south layout', borderColor: null } }, //.. . .Em seguida, adicione os 6 botões restantes], [0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0.1]);//Existem sete objetos no array, então a largura dos sete objetos deve ser definida return form;}
Estas são as partes mais interessantes. Obrigado a todos pela leitura. Espero que seja útil para o seu estudo. Também espero que todos apoiem a VeVb Martial Arts Network.