kbrsh / moon

🌙 The minimal & fast library for functional user interfaces
https://moonjs.org
MIT License
6k stars 200 forks source link

How to use m-for in component template using Webpack #226

Closed sadeghbarati closed 6 years ago

sadeghbarati commented 6 years ago

All details are given in jsfiddle pls take a look

JsFiddle Here

my problem is similar issue #205 but with a little bit of difference. i dont get logic of m-for and item or every name we want and not item or item in items ??? list in lists or item in lists

like moon exampls record in commits

pls explain m-literal:list="list" too

thanks pls help 😢

kbrsh commented 6 years ago

Check this out for an annotated example. Let me know if I answered your question.

sadeghbarati commented 6 years ago

its work 👍 but :

1- which one of props have no effect and must be deleted ? use props just in parent-component or child-component

2- my list include like : Item-1, Item-2, Item-3, Item-4 but show 3 li like 1,2,3

3- in doc u say: Each component is a mini Moon instance,

4- if we use huge file struct we must back to General Moon ??

sadeghbarati commented 6 years ago

MoonIssue.zip ⬅️
pls download file and use npm install then use npm run dev

in this case i provide file issue if parent and child and general moon is separate files

and file struct ⬇️

sadeghbarati commented 6 years ago

dude pls save my day :| 😭 @kbrsh i really tried up from try and get no result ...

kbrsh commented 6 years ago
  1. Props are like arguments you pass to a component. As a result, the root instance and parent component do not require it.
  2. That's because it is rendering the list prop provided to it by the root Moon instance.
  3. Here's a better way of saying it — the root Moon instance is a component.
sadeghbarati commented 6 years ago

You see MoonIssue.zip ? What is your idea about it ?

I'm beginner pls provide an example or explain more

what is root ? General moon ( new Moon )??

Another thing I get from ur comment ( maybe understand maybe not ) we can use new Moon in another component OR pass the root: "#target" option in Moon.component ?

We use props just in one of them or props must be in two place : 1- General moon 2- child-component

sadeghbarati commented 6 years ago

Pls help to pass this problem I swear the god I will not open new issue :laughing: :cry:

kbrsh commented 6 years ago

I don't currently have time to look into your case specifically. Root is new Moon. Basically, there is a class Moon that every component is a subclass of. This means that running new Moon creates a new instance of this class, and running Moon.component and using it in a template will create a new instance of the class. As a result, new Moon and Moon.component take the same options, with the exception of el.

The props are again like arguments to a function. Think of a component like a function of state — you can pass it arguments.

function child(prop) {
  console.log("child created with " + prop);
}

function parent() {
  child("hello");
}

function root() {
  parent();
}

Just like parent provides an argument to child, root could provide the argument to parent in order to pass it down further. This is how a component works. You declare the props that it takes as arguments and any component can pass them down to children.

sadeghbarati commented 6 years ago

@kbrsh

pls look this CODEPEN

Have a look at this codepen link as MoonIssue.zip...

Do not need to do anything, just look at one

I JUST COPY your [ JS Fiddle ] and I separated the files from each component, and using module type file and imported to one codepen

it is the childComponent => Child.js

and its the parentComponent =>Parent.js

and its root or new Moon => App.js

pls read this one too:

every thing works fine if every thing in one file or in one script tag but

if you look at your JS Fiddle 👇 all the component and root [ placed in one script tag ] and components are not Separate Files

its my jsfiddle you update...

<script>
  'use strict';
  // child section component ============================
  const myComponent = Moon.component('my-component', {
    props: ["list"],
    data: function() {
      return {
        list: ['Item - 1', 'Item - 2', 'Item - 3', 'Item - 4']
      }
    },
    // Moon doesn't support m-for as the root element, so I wrapped it in a div
    // Also, you can bind any variable in `m-for`
    // Syntax: `{name} in {array}`
    template: `<div><div class="m-for__problem">
                <ul>
                  <li m-for="item in list">{{item}}</li>
                </ul>
            </div></div>`,
    methods: {
      axiosInComponent: function() {
        alert('wtf');
      }
    },
    hooks: {
      mounted: function() {
        this.callMethod("axiosInComponent", []);
      }
    }
  });

  // parent section and component ========================
  const parentComponent = Moon.component('parent-component', {
    props: ["list"],
    template: `<div class="parent">
                        <my-component m-literal:list="list"></my-component>
            </div>`
  })

  // general section
  const app = new Moon({
    el: "#app",
    data: {
      loopProblem: "i have problem in m-for, for using it in component template u explain it in issue but i dont realy have any idea; https://github.com/kbrsh/moon/issues/205, we must just use `items` like `item in list` ??? because i see diffrence m-for in your examples like `record in commits` realy i dont understand m-for logic :|, let me explain my [ PROBLEM ] => i want to use m-for in components and just fix it in component section not in general `new Moon`, my mean dont need to add two props in component section and general app section, pls explain more about m-literal:list='list', why i create two components ?? because i have too... im using webpack and module scripts for separate files for clean code and simple editing and parent component wrap all child component and just have to write one component tag in html and dont need more component tag in html and parent tag maybe have more componet like header main footer, i use one component just for explain problem..",
      list: [1, 2, 3] // Here I added the list variable instead of a prop because you need to define it somewhere
      // M-literal passes down a prop as a literal expression instead of a
      // string. So doing prop="hello" would pass the javascript string
      // "hello". Doing m-literal:prop="hello" would pass the VARIABLE
      // "hello" from the `data`
    }
  });

</script>

[ this issue seems to come about when components are Separate Files]

like child.js - parent.js - app.js

sadeghbarati commented 6 years ago

If I want to explain briefly: [ cuz u dont have time to check case specifically 🌚 ]

1- i just [COPY] each section in JS Fiddle and created separate files like child.js - parent.js and app.js in codepen

2- i imported them to one, the root or new Moon

3- this issue apear when we use separate files and console threw this error: Moon is not defined

4- data and props doesn't work if we use separate files

kbrsh commented 6 years ago

Moon registers components globally, you don't need to import them to use them. You just need to be able to get the file running to create the component on the Moon library.

// component.js

export function InitComponent(Moon) => {
  Moon.component("Component", { /* options */ });
};

// app.js

import { InitComponent } from "./component.js";

InitComponent(Moon);

// you can now use the component
sadeghbarati commented 6 years ago

i change my all files working on moon to your comment but still have problem

even i changed my Codepen to export function but still have error

your export function have mistake arrow function and must something like this

export initComponent(Moon) => { } let's miss this mistake

You did not understand my problem correctly if you downloaded this file

It does not take much time because it does not contain a lot of files

as I said, two more steps 1-npm install then npm run dev for understanding this nonsense problem

pls download that file to find solution who use WebPack and dont use Production files locally in html

to close this long issue...

kbrsh commented 6 years ago

Ahh I switched between the syntax haha.

Your codepen doesn't work because the child component is still being registered incorrectly. You need to import both child and parent component initialize functions in app.js.

sadeghbarati commented 6 years ago

i think i have to solve problem by my self and look vuejs issue 🚶

its ur repository if u can't solve... :|

kbrsh commented 6 years ago

I gave you a solution. It's your job to apply it — I'm not here to write your code, but am willing to help.

sadeghbarati commented 6 years ago

solution for m-for issue:

global.Moon = require("moonjs")

m-literal:NameOfArray="NameOfArray"

and Props