2012-10-09 3 views
1

У меня есть два CFC, которые являются фасолью с функциями DAO. Я установил наследование, когда дочерний cfc расширяет родительский элемент.Унаследованный CFC не заполняется

Оба объекта имеют одинаковые конструкции; Функции: init, чтение и т. Д. И свойства: ID и т. Д.

Когда я создаю дочерний объект, я передаю идентификатор, который считывает данные, получая родительский идентификатор внешнего ключа для родителя, а затем Super.init () вызывается с соответствующими параметрами.

Мои неожиданные результаты: Идентификатор для дочернего элемента и родительского идентификатора совпадают и являются значением parentID, когда объект возвращается. После супервызов переменные childs.ID перезаписываются. Я предполагаю, что область переменных доступна для обоих, поэтому, когда parent устанавливает переменные.ID, он перезаписывает дочерние переменные.ID. Можно ли этого избежать, не именовав идентификаторы по-разному?

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

Есть ли способ поддерживать одни и те же структуры cfc и заставить эту функциональность работать должным образом?

Заранее спасибо.

<cfcomponent accessors="true" extends="Custom" output="false"> 
<cfproperty name="ID" type="numeric" /> 
<cfproperty name="listID" type="numeric" /> 
<cfproperty name="customfieldID" type="numeric" /> 
<cfscript> 
    variables.dsn = ''; 
</cfscript> 

<cffunction name="init" access="public" output="false" returntype="ListCustom"> 
    <cfargument name="dsn" type="string" required="true" /> 
    <cfargument name="ID" type="numeric" required="true" /> 
    <cfargument name="listID" type="numeric" required="false" default="0" /> 
    <cfargument name="customFieldID" type="numeric" required="false" default="0" /> 
    <cfscript> 
     variables.dsn = arguments.dsn; 
     variables.ID = arguments.ID; 
     variables.listID = arguments.listID; 
     variables.customFieldID = arguments.customFieldID; 
     if (variables.ID){ 
      read(); 
      if (variables.customFieldID){ 
       Super.init(dsn=variables.dsn,ID=variables.customfieldID); 
      } 
     } 
    </cfscript> 
    <cfreturn this /> 
</cffunction> 

<cffunction name="read" access="private" output="false" returntype="void"> 
    <cfquery name="local.q" datasource="#variables.dsn#"> 
     SELECT customfieldID, listID 
     FROM listCustomFields 
     WHERE ID = <cfqueryparam value="#variables.ID#" cfsqltype="cf_sql_integer"> 
    </cfquery> 
    <cfif local.q.recordcount> 
     <cfset variables.listID = local.q.listID /> 
     <cfset variables.customFieldID = local.q.customFieldID /> 
    </cfif> 
</cffunction> 

<cfcomponent accessors="true" output="false"> 

<cfproperty name="ID" type="numeric" /> 
<cfproperty name="fieldName" type="string" /> 

<cfscript> 
    variables.dsn = ''; 
</cfscript> 

<cffunction name="init" access="public" output="false" returntype="Custom"> 
    <cfargument name="dsn" type="string" required="true" /> 
    <cfargument name="ID" type="numeric" required="true" /> 
    <cfargument name="fieldName" type="string" required="false" default="" /> 
    <cfscript> 
     variables.dsn = arguments.dsn; 
     variables.ID = arguments.ID; 
     variables.fieldName = arguments.fieldName; 
     if (variables.ID){ 
      read(); 
     } 
    </cfscript> 
    <cfreturn this /> 
</cffunction> 

<cffunction name="read" access="private" output="false" returntype="void"> 
    <cfquery name="local.q" datasource="#variables.dsn#"> 
     SELECT fieldName 
     FROM CustomField 
     WHERE ID = <cfqueryparam value="#variables.ID#" cfsqltype="cf_sql_integer"> 
    </cfquery> 
    <cfif local.q.recordcount> 
     <cfset variables.fieldName = local.q.fieldName /> 
    </cfif> 
</cffunction> 

+3

Вы можете поделиться некоторыми кодами? Кроме того, в отношениях между родителями и дочерними элементами я не уверен, что родительский родительский путь - это путь. Оба могут расширять «базовый» объект, но не уверен, что дочерний родительский родитель - это путь. –

ответ

1

Во-первых, оба garygilbert и KRC были полезны, указывая на меня в правильном направлении. Спасибо.

Я собрал следующую информацию: И ребенок, и родитель будут разделять одну и ту же область переменных, поэтому при присваивании значения переменным.ID в супер значение child variables.ID было перезаписано.

Аналогично, чтение дочерней функции имеет приоритет над родительской функцией чтения из-за перезаписи функции OO.

Мое скорректированное решение: Установите временный идентификатор, который является дочерним идентификатором до вызова функций Super. Если я передаю идентификатор функции init, функция read вызывается автоматически, я хотел бы избежать этого в родительском объекте, потому что он все равно вызовет чтение ребенка. Я вызываю Super.init (dsn) для инициализации, затем Super.setID (ID) и, наконец, Super.read(). После супервызов я восстанавливаю исходный идентификатор ребенка.

 <cfscript> 
     variables.dsn = arguments.dsn; 
     variables.ID = arguments.ID; 
     variables.listID = arguments.listID; 
     variables.customFieldID = arguments.customFieldID; 
     if (variables.ID){ 
      read(); 
      if (variables.customFieldID){ 
       variables.tempID = variables.ID; 
       Super.init(dsn=variables.dsn); 
       Super.setID(variables.customfieldID); 
       Super.read(); 
       variables.ID = variables.tempID; 
      } 
     } 
    </cfscript> 
0

Я думаю, что причина, почему это происходит потому, что, как CF прицелы cfproperty значения в ПЕРЕМЕННОМ объеме всего объекта, а не в исключительном объеме к CFC (например, общепринятая практика VARIABLES.instance).

Область VARIABLES разделяется между вашим объектом, включая его унаследованный родительский элемент, поэтому, называя значение идентификатора как родительским, так и дочерним, вы фактически просто объявляете его дважды вместо объявления двух отдельных переменных. Затем, когда вы передаете ID на ваш super.init(), он перезаписывает ваше значение ID вашему идентификатору ребенка в значение идентификатора, которое вы передаете в родительский компонент, что приводит к вашему результату. Если вы хотите увидеть это в действии другим способом, попробуйте создать тестовую функцию в своем дочернем элементе, которая разделяет имя переменной в родительском элементе. Назначьте эту переменную значением в вашем super.init() и следите, чтобы ваша дочерняя функция исчезла из вашего объекта.

Так что, чтобы ответить, я не думаю, что вы можете решить проблему, не выполняя то, что вы не хотите делать. Вам нужно будет использовать другое имя для родительского идентификатора или не использовать встроенные функции доступа и вручную записывать все ваши функции getter, устанавливая их в области, исключительной для CFC.

+0

У меня есть половина права; когда вы говорите, что функция чтения не выполняется, я предполагаю, что вы ссылаетесь на функцию init в родительском, вызывающую ее собственное чтение. Как сказал Гэри, этот вызов нужно сделать с помощью супер, чтобы заставить его работать. –

+1

: Есть функции init и read в обоих cfc. Я дал окончательные детали в своем «ответе». Благодаря! – David

2

Поскольку вы расширяете объект, переменная scope как для родителя, так и для ребенка является общей, поэтому variables.id в родительском объекте является таким же variables.id в дочернем, и как дочерний, так и родительский могут получить доступ или перезаписать то, что там хранится ,

Также с расширением родительская функция read никогда не будет вызываться, если функция-функция явно не вызывает ее с помощью super.read().

Кроме того, если вы не настроили приложение и ваши компоненты на использование ORM, теги cfproperty предназначены только для веб-сервисов.

+1

@garygilbert: Спасибо, что ответили. Я укажу, что «только для веб-сервисов» больше не применимо для версии 9+ CF-сервера. Использование cfproperty создаст «виртуальные» геттеры и сеттеры для cfproperties, если атрибут компонента, accessors, установлен в true. – David

+0

@ Давид правда, что я забыл о неявных сеттерах и геттерах, которые были введены в CF9 – garyrgilbert

Смежные вопросы