Как внедрить пользовательский компонент из js в nativescript?

Предположим, я создаю небольшой компонент, который принимает ввод и устанавливает метку для его отображения.

приложение/компоненты/testComponent/testComponent.xml:

<Label id="someLabel" loaded="onLoad"/>

приложение/компоненты/testComponent/testComponent.js:

exports.onLoad = args => {
    const obj = args.object;

    const label = obj.getViewById('someLabel');
    label.text = obj.someString || 'no string given';
};

Теперь я могу использовать этот компонент на любой из своих страниц.

<Page xmlns="http://schemas.nativescript.org/tns.xsd"
      xmlns:testComponent="components/testComponent">
    <StackLayout>
        <testComponent:testComponent someString="hello {N}"/>
    </StackLayout>
</Page>

Кажется, это официальный способ сделать это, и он работает. Но есть ли способ внедрить этот компонент на страницу, используя только javascript?


person Akash    schedule 26.04.2016    source источник


Ответы (2)


Да, декларативный пользовательский интерфейс (то есть xml) на самом деле является системой построения, которая анализирует xml и генерирует JS, поэтому вам не нужно этого делать.

Поэтому, если вы хотите сделать это вручную, вы должны оставить свой код компонента в покое и изменить код основного экрана следующим образом:

<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="onLoad">
    <StackLayout id='sl'>

    </StackLayout>
</Page>

Первое, что вы заметите, это то, что мы дали странице событие load, у вас должно быть место, где вы действительно можете запустить свой код, чтобы прикрепить свой компонент к визуальному дереву. Второе, что мы сделали, это добавили в StackLayout идентификатор; технически это на самом деле не нужно - вы можете перемещаться по дереву NS и находить правильный StackLayout; но для простоты добавление идентификатора делает его намного проще.


Таким образом, код JS на вашей странице будет таким:

var builder = require('ui/builder');
var fs = require('file-system');

exports.onLoad = function(args) {
  // Get our current Page that is being loaded
  var page = args.object;

  // Find our StackLayout
  var stackLayout = page.getViewById('sl');

  // Load our JS for the component
  var path = fs.knownFolders.currentApp().path;
  var componentJS = require(path + '/components/testComponent/testComponent.js');

  // Actually have the builder build the Component using the XML & JS.
  var component = builder.load(path + '/components/testComponent/testComponent.xml', componentJS);

  // And add our component to the visual tree
  stackLayout.addChild(component);
};

Я считаю, что, поскольку вы добавляете дочерний элемент в загруженное событие, событие загрузки вашей страницы в дочернем компоненте будет запущено, но не держите меня в этом. Если это не так, вы можете вручную запустить его одновременно с добавлением...

person Nathanael    schedule 26.04.2016

где путь к файлу — это скрипт или даже класс, экземпляр которого может создать функция обратного вызова. Это как если бы он загружался при загрузке страницы и отображался в большинстве консолей инструментов разработчика.

        var uuid='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
             var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
             return v.toString(16);
        });
             var url = filepath + "?" + uuid;//prevent caching - does not work with ajax setup
             try {
                    $.getScript(url, "callbackfunctionname('" + filepath + "')");//getScript callback seems broken so use own
             }
             catch (e) {
                    //error handle
             }
person Datadimension    schedule 26.04.2016
comment
Этот код не имеет ничего общего с NativeScript. Похоже, это код на основе браузера... - person Nathanael; 26.04.2016
comment
Я предлагаю, когда вы запрашиваете решение только для javascript, вы научитесь распознавать javascript как действительно javascript, а не очень расплывчатый термин «код на основе браузера». Как вы можете хотеть решение javascript, которое на самом деле не является javascript? Хотя ответ выше выглядит нормально, это не чистый javascript и создается при загрузке страницы, а не вводится - person Datadimension; 26.04.2016
comment
Запрос был о том, как загружать пользовательские компоненты конкретно в NativeScript через JavaScript. NativeScript не является браузером, и поэтому такие вещи, как $ (из JQuery), не будут работать. Кроме того, система построения экрана в NativeScript не имеет традиционной модели DOM; это означает, что даже полностью действительный код JavaScript, разработанный для браузера, не будет работать на нем. Поясняет ли это, почему я сказал код на основе браузера? - person Nathanael; 26.04.2016
comment
Могу ли я предложить пересмотреть вопрос в этом случае вместо того, чтобы голосовать за людей, которые не умеют читать мысли? - person Datadimension; 26.04.2016
comment
Извините, насчет этого - я потерял баллы, когда я также проголосовал против него, поэтому не похоже, что в моих интересах проголосовать против вашего вопроса - причина, по которой я это сделал, заключается в том, что это совершенно неправильно для платформы. Ваш код отлично подходит для браузера, использующего JQuery, и мне нравится ваш трюк с UUID. Что касается чтения мыслей, то внизу вопроса находится тег NativeScript. - person Nathanael; 26.04.2016